List View(列表视图)
2016-07-24 16:24
519 查看
概述
列表视图是一个视图组,它以可滑动列表的方式展示了许多项目。列表项通过使用一个Adapter来自动填充,适配器(
Adapter)将数据从源端(例如一个数组或数据库的查询结果)提取内容并将内容填入每一个项目中去。
如何使用适配器来填充数据,请阅读Building
Layouts with an Adapter.
使用装填器(Loader )
使用CursorLoader是标准的用来查询异步任务中游标(Cursor)的方法,可以避免阻塞你app的主线程。当CursorLoader接受了Cursor的结果,LoaderCallbacks收到一个onLoadFinished()回调,onLoadFinished()在你的适配器有新的游标和列表视图需要显示结果并更新你的适配器时被调用。
更多关于如何使用loader 的方法,请查阅 Loaders开发向导(app
components /activities )。
Example
下面用一个ListActivity,举例,这是一个只包含了listview
的activity 。它为 Contacts
Provider 执行了一个查询名字和电话号码的操作。
这个activity 实现了
LoaderCallbacks接口,为了使用
CursorLoader来为list
view 动态加载视图。
public class ListViewLoader extends ListActivity
implements LoaderManager.LoaderCallbacks<Cursor> {
// 这是一个被用来展示列表数据的adapter
SimpleCursorAdapter mAdapter;
// 这是我们将要查找的内容(contacts)列
static final String[] PROJECTION = new String[] {ContactsContract.Data._ID,
ContactsContract.Data.DISPLAY_NAME};
// 这是筛选标准(选择语句)
static final String SELECTION = "((" +
ContactsContract.Data.DISPLAY_NAME + " NOTNULL) AND (" +
ContactsContract.Data.DISPLAY_NAME + " != '' ))";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 创建一个进度条来展示列表加载进度
ProgressBar progressBar = new ProgressBar(this);
progressBar.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT, Gravity.CENTER));
progressBar.setIndeterminate(true);
getListView().setEmptyView(progressBar);
// 必须将进度条加载到更布局上
ViewGroup root = (ViewGroup) findViewById(android.R.id.content);
root.addView(progressBar);
// 使用游标适配器(cursor adapter), 指定哪一列与哪一个视图相匹配
String[] fromColumns = {ContactsContract.Data.DISPLAY_NAME};
int[] toViews = {android.R.id.text1}; // The TextView in simple_list_item_1
// 创建一个空的适配器,我们将用它来展示加载的数据
// 我们为游标参数传递了null, 然后在 onLoadFinished()中更新它
mAdapter = new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_1, null,
fromColumns, toViews, 0);
setListAdapter(mAdapter);
// 准备加载器(loader). 重新连接一个已经存在的或开启一个新的。
getLoaderManager().initLoader(0, null, this);
}
// 当一个新的加载器被创建时调用
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
// 现在,创建并返回一个CursorLoader,它只处理创建一个数据显示的游标
return new CursorLoader(this, ContactsContract.Data.CONTENT_URI,
PROJECTION, SELECTION, null, null);
}
// 当事先创建的加载器已经完成加载时调用
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
// 交换新游标 (一旦我们返回,框架将会处理关闭老的游标)
mAdapter.swapCursor(data);
}
// 当预先创建的加载器被重新设置时调用,让数据不可用
public void onLoaderReset(Loader<Cursor> loader) {
//当最后的游标提供给onLoadFinished()并关闭时调用
// 我们需要确保再也不会使用它了
mAdapter.swapCursor(null);
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
// 当列表项被点击时,在这响应操作
}
}
注:因为该案例执行了一个在 Contacts
Provider,中的查询操作,如果你想运行该代码,你的应用必须在配置文件中请求READ_CONTACTS权限:<uses-permission
android:name="android.permission.READ_CONTACTS" />
使用适配器创建布局(Building Layouts with an Adapter)
当你的layout内容是动态的或者不是事先确定的,你就可以在使用AdapterView的子类在运行时去填充layout。
AdapterView的一个子类可以使用一个Adapter来把数据捆绑到layout上。
这个
Adapter发挥着数据源和
AdapterViewLayout之间的“中间人”的作用--
Adapter获取数据(从一个比如数组或者数据库查询之类的来源),然后把每一个条目转变成能被添加到
AdapterViewLayout里的view(的内容)。
常见的被Adapter支持的layout如下:
List View
显示一个可滚动的单列列表。
Grid View
显示一个可滚动的行列组成的网格。
Filling an adapter view with data
你可以为Adapter绑定AdapterView以此来填充
ListView或者
GridView,这个
Adapter从外部资源中获取数据,创建一个代表着每一个数据条目的
View。
Android提供了一些对提取不同类型数据以及为
AdapterView创建view有用的
Adapter的子类。如下是两个最常用的Adapter:
ArrayAdapter
当你的数据源是数组的时候使用这个Adapter。默认情况下,
ArrayAdapter靠
为每一个数组项调用
toString()和把内容放置在
TextView的方式为每一个数组项创建一个view。
举个例子:如果你有一个想要展示在
ListView的字符串数组,用构造器初始化一个新的
ArrayAdapter来为每一个字符串或字符串数组指定layout:
ArrayAdapter adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, myStringArray);
这个构造器的参数是:
你的app的
上下文。
包含了为数组中每个字符串指定内容的
TextView的layout。
字符串数组。
然后简单地在你的
ListView中调用
setAdapter()。
ListView listView = (ListView) findViewById(R.id.listview); listView.setAdapter(adapter);
为了定制每一个条目的外观,你可以为数组中每个对象重写
toString()方法。或者,为了给每一个不是
TextView的条目创建view,
(举例来说,如果你想为每一个数组项建立
ImageView)你要为每个item继承
ArrayAdapter类并重写
getView()方法来返回你想要view类型。
SimpleCursorAdapter
当你的数据来自于一个
Cursor的时候使用这个Adapter。
当使用
SimpleCursorAdapter的时候,你必须为cursor中每一行指定一个Layout以及cursor中的哪一列应该被插入到layout的哪一个view中去。
举例来说,如果你想创建人们名字和电话号码的列表,你就可以执行一个返回包含了一个
Cursor的查询,在这个
Cursor中,每行为一个人,列包含人名,电话号码之类的信息。
然后你就可以创建一个在layout中指定你想要的
Cursor的哪些列的字符串数组,以及指定对应的每一列应当被放置的所在的view
的整形数组:
String[] fromColumns = {ContactsContract.Data.DISPLAY_NAME,ContactsContract.CommonDataKinds.Phone.NUMBER};int[] toViews = {R.id.display_name, R.id.phone_number};
当你实例化
SimpleCursorAdapter类的时候,
传递layout给
Cursor包含的每一个result使用。然后这两个数组:
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.person_name_and_number, cursor, fromColumns, toViews, 0);ListView listView = getListView(); listView.setAdapter(adapter);
然后
SimpleCursorAdapter就会使用提供的layout将每一个
fromColumns插入到对应的
toViewsview中,并以此在
Cursor中为每一行创建view。
如果在你的应用的生命周期当中,你改变了底层可以被Adapter读取的数据,你应该调用
notifyDataSetChanged()。
这样能够通知哪些相关的view:数据已经改变了,是时候刷新了。
Handling click events
你可以实现AdapterView.OnItemClickListener接口在
AdapterView的每一个item上回应点击事件。
// Create a message handling object as an anonymous class.private OnItemClickListener mMessageClickedHandler = new OnItemClickListener() {public void onItemClick(AdapterView parent, View v, int position, long id) {// Do something in response to the click}}; listView.setOnItemClickListener(mMessageClickedHandler);
本小结来源: http://android-doc.com/guide/topics/ui/declaring-layout.html#AdapterViews
相关文章推荐
- Android布局的小窍门?
- Web布局连载——两栏固定布局(五)
- 样式表CSS布局经验
- 在winform下实现左右布局多窗口界面的方法之续篇
- css网页布局中注意的几个问题小结
- DL.DT.DD实现左右的布局简单例子第1/2页
- 使用CSS框架布局的缺点和优点小结
- div+CSS网页布局的意义与副作用原因小结第1/2页
- 在winform下实现左右布局多窗口界面的方法
- Android布局技巧之创建可重用的UI组件
- Android编程之代码创建布局实例分析
- CSS顶级技巧大放送,div+css布局必知
- php结合安卓客户端实现查询交互实例
- 用div实现像table一样的布局方法
- Bootstrap三种表单布局的使用方法
- 精彩的Bootstrap案例分享 重点在注释!(选项卡、栅格布局)
- 第七篇Bootstrap表单布局实例代码详解(三种表单布局)
- jQuery EasyUi实战教程之布局篇
- jQuery EasyUI 布局之动态添加tabs标签页
- jquery自适应布局的简单实例