ListView作为列表的常用控件,
通常使用MVC的模式来应用,
View自身就是V, 而C是所需要的adapter
一般情况下可以使用ArrayAdapter,CursorAdapter,BaseAdapter的实现类来绑定数据源
常见技巧(来源于API DEMOS,其他设置单选多选,cursor的使用,添加图片等参见Views/Lists中例子)
1.带Separators的List,从而该行可以显示但没有click效果与事件
adapter重写某些属性函数
@Override
public boolean areAllItemsEnabled() {
return false;
}
@Override
public boolean isEnabled(int position) {
return !mStrings[position].startsWith("-");
}
2.带首字母索引的列表效果(带屏幕中间的字母图)
设置onScroll监听,判断firstVisibleItem中的首字母
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
if (mReady) {
char firstLetter = mStrings[firstVisibleItem].charAt(0);
if (!mShowing && firstLetter != mPrevLetter) {
mShowing = true;
mDialogText.setVisibility(View.VISIBLE);
}
mDialogText.setText(((Character)firstLetter).toString());
mHandler.removeCallbacks(mRemoveWindow);
mHandler.postDelayed(mRemoveWindow, 3000);
mPrevLetter = firstLetter;
}
}
3.类似对话软件的ListView,从底部增加ITEM
<ListView android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:stackFromBottom="true"
android:transcriptMode="normal"/>
4.不滚动时异步加载的ListView
判断scrollState,当是IDLE时才去加载相应的ITEM
public void onScrollStateChanged(AbsListView view, int scrollState) {
switch (scrollState) {
case OnScrollListener.SCROLL_STATE_IDLE:
mBusy = false;
int first = view.getFirstVisiblePosition();// 当前第一个可见ITEM在LIST中位置
int count = view.getChildCount();// 当前可见ITEM数目
for (int i=0; i<count; i++) {
TextView t = (TextView)view.getChildAt(i);
if (t.getTag() != null) {
t.setText(mStrings[first + i]);
t.setTag(null);
}
}
mStatus.setText("Idle");
break;
case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:// 手带着列表滑动,未离开屏幕
mBusy = true;
mStatus.setText("Touch scroll");
break;
case OnScrollListener.SCROLL_STATE_FLING:// 列表仍在滑动,手离开了屏幕,fling有冲的意思
mBusy = true;
mStatus.setText("Fling");
break;
}
}
5.效率较高的adapter,较常用
public View getView(int position, View convertView, ViewGroup parent) {
// A ViewHolder keeps references to children views to avoid unneccessary calls
// to findViewById() on each row.
ViewHolder holder;
// When convertView is not null, we can reuse it directly, there is no need
// to reinflate it. We only inflate a new View when the convertView supplied
// by ListView is null.
if (convertView == null) {
convertView = mInflater.inflate(R.layout.list_item_icon_text, null);
// Creates a ViewHolder and store references to the two children views
// we want to bind data to.
holder = new ViewHolder();
holder.text = (TextView) convertView.findViewById(R.id.text);
holder.icon = (ImageView) convertView.findViewById(R.id.icon);
convertView.setTag(holder);// 将引用保存到tag中
} else {
// Get the ViewHolder back to get fast access to the TextView
// and the ImageView.
holder = (ViewHolder) convertView.getTag();// 快速取回引用,减少了子view查找及引用赋值的时间
}
// Bind the data efficiently with the holder.
holder.text.setText(DATA[position]);
holder.icon.setImageBitmap((position & 1) == 1 ? mIcon1 : mIcon2);
return convertView;
}
// 内部类,标明每个ITEM中的子内容
static class ViewHolder {
TextView text;
ImageView icon;
}