本篇随笔将讲解一下Android当中比较常用的两个布局容器--ScrollView和HorizontalScrollView,从字面意义上来看也是非常的简单的,ScrollView就是一个可以滚动的View,这个滚动的方向是垂直方向的,而HorizontalScrollView则是一个水平方向的可以滚动的View。本篇随笔可能描述性的知识比较少,最主要还是通过代码来看看如何使用这两个View。
一、ScrollView的简单介绍
首先来看看ScrollView和HorizontalScrollView这两个View的定义。ScrollView和HorizontalScrollView都是一个布局容器,里面可以放入child View控件,我们通过其继承关系看到,ScrollView和HorizontalScrollView这两个类是ViewGroup的一个间接子类。
java.lang.Object android.view.View android.view.ViewGroup android.widget.FrameLayout android.widget.ScrollView
java.lang.Object android.view.View android.view.ViewGroup android.widget.FrameLayout android.widget.HorizontalScrollView
因为ScrollView和HorizontalScrollView只是两种滚动方向不同的View而已,其他方面都基本相同,所以下面只单单以ScrollView来讲解。
通过使用ScrollView,我们可以滚动其里面的子View控件,这样就允许我们控件的高度可以大于我们实际屏幕的尺寸高度。ScrollView是一个FrameLayout,至于什么是FrameLayout,简单的来说,FrameLayout通常被用来设计成在屏幕上占用一块地方并且里面只有一个Item,我们常用到的例如DatePicker、TimePicker这些控件都是属于FrameLayout布局的。因此在ScrollView当中,也通常只包含一个子元素,并且这个子元素也是一个布局文件,这样我们才能在这个布局文件里面添加我们想要的任何子控件,从而实现滚动的效果。
对于ScrollView来说,因为其是垂直方向上的滚动布局,因此通常我们给其添加一个LinearLayout的子元素,并且设置orientation为vertical(垂直方向的)。下面我们通过一个小例子来看看如何使用我们的ScrollView来展示多张图片,并且实现图片的垂直方向的滚动。
首先我们定义一个ScrollView,因为ScrollView也是一个ViewGroup,所以我们可以直接使用ScrollView作为我们的xml文件的根元素:
我们看到,在ScrollView元素下面我们还给其定义了一个LinearLayout,并且设置了其方向为垂直方向的线性布局。我们添加图片的操作放在了代码中来完成。下面来看一下ScrollViewActivity这个类:
public class ScrollViewActivity extends Activity{ private LinearLayout layout; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.layout_scrollview); layout = (LinearLayout) findViewById(R.id.layout); for(int i = 0; i < 8; i++) { // 通过资源文件来获得指定一个Drawable对象 Drawable drawable = getResources().getDrawable(R.drawable.kk_hero); ImageView p_w_picpathView = new ImageView(this); p_w_picpathView.setImageDrawable(drawable); layout.addView(p_w_picpathView); } }}
我们看到,这个Activity非常的简单,因为LinearLayout就是一个ViewGroup对象,所以我们可以动态的给其添加我们想要的View控件,这里我们给其添加了8张图片,我们来看看效果:
我们看到,在Activity启动以后,就会在其下面生成8个ImageView的对象,并且这几张图片是可以在垂直方向上滚动的。
二、通过ScrollView实现从服务器端获取一条新闻,显示在界面上
接下来咱们通过ScrollView来做一个稍微实际一点的例子,我们经常会用手机来看新闻,当然一篇新闻是从服务器端获取过来的数据,而且可能一篇新闻里面有很多的内容,因此我们需要使用一个可以滚动的布局来显示我们的新闻内容,而TextView本身是可以实现文本的滚动显示的,但是结合ScrollView和TextView可以有更好的效果。
我们服务器端就很简单,让我们的应用程序访问服务器端的一个Html的文件,我们知道Html的文件里面会有许多的Html标签,那么我们如果想在Android上也能够显示标签的样式,就不能单单的只是将获取到的文本内容展示出来而已,这里就需要用的Android提供的一个 Html 的类,用它来处理我们从服务器端获得的Html的字符串内容:
我们的布局文件还是使用的刚才那一个:
因为要访问网络,所以这里需要新建一个HttpUtils的工具类,来获得服务器端的文本内容:
public class HttpUtils{ /** * 访问服务器端的内容 * @param path 访问的url地址 * @param encode 编码方式 * @return 返回String类型的值 */ public static String getDataFromServer(String path, String encode) { String result = ""; HttpClient httpClient = new DefaultHttpClient(); try { HttpPost httpPost = new HttpPost(path); HttpResponse httpResponse = httpClient.execute(httpPost); if (httpResponse != null && httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { result = EntityUtils.toString(httpResponse.getEntity(), "utf-8"); } } catch (Exception e) { e.printStackTrace(); } finally { httpClient.getConnectionManager().shutdown(); } return result; }}
我们还是用之前那个Activity:
public class ScrollViewActivity extends Activity{ private LinearLayout layout; private ProgressDialog dialog; private TextView textView; private final String PATH = "http://172.25.152.34:8080/httptest/news.html"; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.layout_scrollview); dialog = new ProgressDialog(this); dialog.setTitle("提示信息"); dialog.setMessage("loading......"); dialog.setCancelable(false); dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); layout = (LinearLayout) findViewById(R.id.layout); textView = new TextView(this); layout.addView(textView); new MyTask().execute(PATH); } public class MyTask extends AsyncTask{ @Override protected void onPreExecute() { dialog.show(); } @Override protected String doInBackground(String... params) { String result = HttpUtils.getDataFromServer(params[0], "utf-8"); return result; } @Override protected void onPostExecute(String s) { // Html类的fromHtml方法可以处理一个Html的字符串文本,这样就可以根据Html的标签在手机上展示其样式 Spanned spanned = Html.fromHtml(s); textView.setText(spanned); // 给TextView设置一个方法,传一个LinkMovementMethod对象进去,这样当文本中如果有href链接时,系统会自动打开浏览器跳转到该href上 textView.setMovementMethod(new LinkMovementMethod()); dialog.dismiss(); } }}
因为要访问网络数据,所以我们需要开启一个AsyncTask的一部任务,我们来看看onPostExecute方法,在获取到服务器端的Html文本内容后,我们通过Android提供的Html.fromHtml方法可以处理我们的Html文本,将Html的标签转化为我们需要的样式显示,但是这里要注意一点,这里并不会处理所有的Html的表情,例如<img>我们来看看Android官方API对这个方法的描述:
public static Spanned fromHtml (String source)Returns displayable styled text from the provided HTML string. Anytags in the HTML will display as a generic replacement p_w_picpath which your program can then go through and replace with real p_w_picpaths.This uses TagSoup to handle real HTML, including all of the brokenness found in the wild.
如果文本当中有<img>标签,那么这个方法就会用一个默认的图片来代替我们的<img>标签中的图片,我们可以自己写一个Html.ImageGetter来加载我们自己想要的图片。
同时,因为文本内容中可能有href链接,因此我们可以通过 textView.setMovementMethod(new LinkMovementMethod()); 来绑定一个LinkMovementMethod,这样在点击链接的时候,就会调用浏览器跳转到该链接上。
相信通过前面的讲解,大家对ScrollView有了进一步的认识,这里并没有讲太多的HorizontalScrollView的知识,因为这个其实是和ScrollView基本上是一样的,只不过一个是垂直方向的滚动,而HorizontalScrollView是水平方向的滚动,同样HorizontalScrollView也是一个FrameLayout,因此我们通常给其定义一个水平方向布局的LinearLayout子元素,这样我们在里面添加的View子控件就可以在水平方向上滚动显示了。
三、总结
本篇随笔主要讲解了一下ScrollView和HorizontalScrollView的知识,因为这两个布局容器比较简单,因此基本上概念性的东西讲的少,主要还是通过代码来了解了ScrollView的使用方式,而对于HorizontalScrollView,其使用方式大同小异,大家可以通过Android官方API来了解更多有关这两个控件的知识。