注: 这是“ListView建议和技巧 ”系列文章中的第一篇。在Android上开发,经常需要显示大的数据集合(通信录、歌曲等等)。大多情况下,这些数据都是类似的并可以通过ListView控件进行统一显示。ListView在Android界面中使用时大多是原本的样子。但是,基于ListView的应用可以通过一些简单的技巧进行定制、优化或者修饰。该系列博客就是介绍一些可以用于加强和改进应用的一些技巧。
简介
在应用中显示一个数据集时,推荐处理如下一些情形:
从用户的角度看,两种情形有不同的界面很重要。确实,它可以帮助用户区分两种“数据”状态。在开发应用时不要忘了这点。
数据为空时的视图(空视图)
ListView或者更广义地说是AdapterView(Gallery、GridView等等)可以很简单地处理空视图情形。AdapterView公开了一个称作setEmptyView(View)的方法来讲一个View绑定到自身。一旦设定了数据为空时的视图,AdapterView就会根据地层Adapter的状态(是否为空)来隐藏或显示该视图。
AdapterView和空视图在可见性方面是互斥的,如果空视图可见(View.VISIBLE),AdapterView就将其视图的可见性设置成View.GONE,相反情形也类似。AdapterView根据如下条件判断其是否为空:
ListActivity
Android框架还提供了一个在界面中使用ListView的很方便的方法。Android提供了一个专用的Acitivity:ListActivity。在通过setContentView方法设定一个新的布局时,ListActivity就自动查找一个标识符是android.R.id.list的ListView并开始管理它。它还会查找一个标识符是android.R.id.empty的视图。一旦存在这样的视图,就会被直接设置成之前ListView的数据为空时的视图。这样,在ListActivity中处理数据为空时的视图就很简单,仅仅需要在布局中加入一个android:id属性是@android:id/empty的视图。
示例
为了展示下如何配置处理数据为空时的视图的代码,我制作了一个简单的应用。该应用仅仅显示带有一个ListView和两个Button的界面。两个按钮帮助你清空或者填充ListView的数据。可以从如下链接获取到应用的完整代码:
ListViewTipsAndTricks archive
正如之前看到的,我们会使用ListActivity让代码尽可能简单清晰。所需要做的唯一一件事情就是在布局中包括一个标识符是@android:id/empty的视图。ListActivity会处理所有的事情!如下的布局有三部分组成:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_;fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<FrameLayout
android:layout_;fill_parent"
android:layout_height="0dp"
android:layout_weight="1">
<ListView
android:id="@android:id/list"
android:layout_;fill_parent"
android:layout_height="fill_parent" />
<ViewStub
android:id="@android:id/empty"
android:layout_;wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout="@layout/empty" />
</FrameLayout>
<LinearLayout
style="@android:style/ButtonBar"
android:layout_;fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:layout_;0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/set_empty"
android:onClick="onSetEmpty" />
<Button
android:layout_;0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/set_data"
android:onClick="onSetData" />
</LinearLayout>
</LinearLayout>
提示: 你们可能注意到了,我使用了一个ViewStub作为空视图。ViewStub使得你可以在需要的时候(这就是即时填充)填充视图。在之前的例子中,@layout/empty布局仅仅在ViewStub的可视性变成View.VISIBLE后被填充。一旦@layout/empty视图被填充,它就会在全局布局中替换ViewStub。如果你不熟悉该类,建议查看下ViewStub文档。
这样在一个简单的ListActivity中就可以使用该布局了:
package com.cyrilmottier.android.listviewtipsandtricks;
import android.app.ListActivity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
public class EmptyListActivity extends ListActivity {
private static final String EMPTY[] = {};
private static final String CHEESES[] = {
"Abbaye de Belloc",
// ...
"Zanetti Parmigiano Reggiano"
};
private CheeseAdapter mAdapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.empty_list);
mAdapter = new CheeseAdapter(CHEESES);
setListAdapter(mAdapter);
}
public void onSetEmpty(View v) {
mAdapter.changeData(EMPTY);
}
public void onSetData(View v) {
mAdapter.changeData(CHEESES);
}
private class CheeseAdapter extends BaseAdapter {
private String[] mData;
public CheeseAdapter(String[] data) {
mData = data;
}
public void changeData(String[] data) {
mData = data;
notifyDataSetChanged();
}
@Override
public int getCount() {
return mData.length;
}
@Override
public String getItem(int position) {
return mData[position];
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = getLayoutInflater().inflate(R.layout.text_item, parent, false);
}
((TextView) convertView).setText(getItem(position));
return convertView;
}
}
}
就是这些了,简单吧?处理ListView数据为空时的情形可以很简单。在开发Android应用时,不要吝惜添加空视图。在使用解释文字的同时加入别出心裁的Drawable会比什么都不显示好…剩下的就靠你的想象力了!
原文链接:http://android.cyrilmottier.com/?p=422