ScrollView——官方文档如此介绍:ScrollView是一个布局容器,可滚动允许比她显示比她显示区域大的的图层次结构。ScrollView是一个FrameLayout,所以说只能存放一个子控件(子控件包含滚动的内容)。
HorzontalScrollView同ScrollView原理一致,只是是水平滚动。
值得注意的是:
1、ListView不要作为ScrollView的子控件,一个原因是ListView需要关注自己的滚动,另一个更重要的原因就是这样会降低ListView的效率。
2、在使用过程中,如果ScrollView和HorizontalScrollView中的View太多就不建议使用这两个控件(效率太低,更新View时容易出现阻塞)。
3、如果对ScrollView的子控件布局设置成水平时,不会有滚动效果,同理HorizontalScrollView的子控件设置成垂直时也不会有滚动效果。比如下面代码:
<ScrollView
android:layout_above="@+id/HorizontalScrollView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_margin="5dp"
android:fillViewport="true"
android:background="@color/button_focused_color" >
<LinearLayout
android:id="@+id/vertical_scroll_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
</LinearLayout>
</ScrollView>
无论LinearLayout中有多少的内容,都只能看到一行内容。
下面是一个简单实用这两个控件的例子,先看看效果图:
在下面是一个水平的ScrollView,上面大屏中的内容时垂直的ScrollView。
在进入该界面的时候我们看到有一段时间是没有填充内容的,这里才在里面创建了100个View。
以下为该部分内容代码:
1、布局文件widget_scroll_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ScrollView
android:layout_above="@+id/HorizontalScrollView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_margin="5dp"
android:fillViewport="true"
android:background="@color/button_focused_color" >
<LinearLayout
android:id="@+id/vertical_scroll_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
</LinearLayout>
</ScrollView>
<HorizontalScrollView
android:id="@+id/HorizontalScrollView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="10dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:background="@color/button_drawable_pressed_end" >
<LinearLayout
android:id="@+id/horizontal_scroll_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
</LinearLayout>
</HorizontalScrollView>
</RelativeLayout>
package com.xy.zt.selfdefinewieget;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.io.File;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class WidgetScrollViewActivity extends Activity {
public static final int MSG_SCROLL_DATA = 104;
private ExecutorService mExecutor;
private Future<List<String>> mListFileTask;
private LinearLayout mHorizontal;
private LinearLayout mVertical;
private LayoutInflater mInflater;
private static final Callable<List<String>> LIST_FILES = new Callable<List<String>>() {
public List<String> call() throws Exception {
File rootDir = Environment.getRootDirectory();
LinkedList<File> queue = new LinkedList<File>();
ArrayList<String> result = new ArrayList<String>(100);
queue.offer(rootDir);
File tmpFile, tmpDirAllFile[];
while ((tmpFile = queue.poll()) != null) {
if (tmpFile.isDirectory()) {
tmpDirAllFile = tmpFile.listFiles();
if (tmpDirAllFile != null) {
for (File f : tmpDirAllFile) {
queue.offer(f);
}
}
} else {
result.add(tmpFile.getName());
}
}
return result;
}
};
Handler mHandler = new Handler() {
@SuppressWarnings("unchecked")
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_SCROLL_DATA:
List<String> datas;
try {
datas = (List<String>) msg.obj;
if (datas == null)
return;
} catch (ClassCastException e) {
return;
}
int len = datas.size();
if (len > 100)
len = 100;
TextView tv;
for (int i = 0; i < len; i++) {
tv = (TextView) mInflater.inflate(R.layout.scroll_text_view_item, null);
tv.setText(datas.get(i));
mVertical.addView(tv);
tv = (TextView) mInflater.inflate(R.layout.scroll_text_view_item, null);
tv.setText(datas.get(i));
mHorizontal.addView(tv);
}
}
;
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.widget_scroll_layout);
init();
mExecutor = Executors.newCachedThreadPool();
mListFileTask = mExecutor.submit(LIST_FILES);
mExecutor.submit(new Runnable() {
@SuppressLint("HandlerLeak")
public void run() {
List<String> datas = null;
;
try {
datas = mListFileTask.get();
} catch (InterruptedException e) {
} catch (ExecutionException e) {
}
Message msg = mHandler.obtainMessage(MSG_SCROLL_DATA);
msg.obj = datas;
mHandler.sendMessage(msg);
}
});
}
private void init() {
mInflater = LayoutInflater.from(this);
mHorizontal = (LinearLayout) findViewById(R.id.horizontal_scroll_layout);
mVertical = (LinearLayout) findViewById(R.id.vertical_scroll_layout);
}
@Override
protected void onDestroy() {
super.onDestroy();
mExecutor.shutdown();
}
}
上述代码中关于线程详细的解释参见文章
一步一步学android控件(之六) —— MultiAutoCompleteTextView
在handleMessage中可以看到一句
if (len > 100) len = 100;
如果,文件多于100个,则取前100个文件显示,多余的丢弃。
3、ViewData.java中添加如下内容(本部分内容可选)
public static final int WIDGET_SCROLL_ID = IMAGE_SWITCHER_ID + 1;
public static final String WIDGET_SCROLL_NAME = "Scroll Views";
private static final ViewData mScrollViews = new ViewData(WIDGET_SCROLL_NAME,
WIDGET_SCROLL_ID);
View_Datas.add(mScrollViews);
在WidgetsAdapter的handleItemClicked函数中添加如下内容:
case ViewData.WIDGET_SCROLL_ID:
intent.setClass(mContext, WidgetScrollViewActivity.class);
mContext.startActivity(intent);
break;
ScrollView和HorizontalScrollView就介绍到这里,下一篇 ListView和ExpandableListView。