ViewHolder模式充分利用了ListView的视图缓存机制,避免了每次调用getView()
时都去通过findViewById()
实例化控件
使用ViewHolder
非常简单,只需要在自定义的Adapter
中定义一个内部类,并将布局中的控件作为成员变量,代码如下:
public final class ViewHolder{
public ImageView img;
public TextView text;
}
然后在getView()
方法中通过视图缓存机制重用即可:
@Override
public View getView(int position,View convertView,ViewGroup parent){
ViewHolder holder = null;
//先判断convertView是否为null
holder = new ViewHolder();
convertView = LayoutInflater.from(mContext).inflate(R.layout.list_item.xml,null);
holder.img = (ImageView)convertView.findViewById(R.id.img);
holder.text = (TextView)convertView.findViewById(R.id.text);
convertView.setTag(holder);
}else{
holder = (ViewHolder)convertView.getTag();
}
holder.img.setBackgroundResource(R.drawable.ic_launcher);
holder.text.setText(mData.get(position));
return convertView;
}
使用如下代码为ListView设置分割线
android:divider="@android:color/darker_gray"
android:dividerHeight="10dp"
//把分割线设置为透明
android:divider="@null"
同样也可以设置drawable资源为分割线。
android:scrollbars="none"
android:listSelector="#00000000"
listView.setSelection(position);
这个方法类似于scrollTo()
是瞬间完成移动的,可以使用下面的代码完成平滑移动:
listView.smoothScrollBy(distance,duration);
listView.smoothScrollByOffset(offset);
listView.smoothScrollToPosition(index);
mDatas.add("new");
adapter.notifyDataSetChanged();
要注意的是mDatas必须指向和Adapter中引用的相同的mDatas。
for(int i = 0;i < mAdapter.getItemCount();i++){ View item = mListView.getChildAt(i); }
8.处理空的ListView
当ListView中的数据为空时可以通过setEmptyView()
方法来指定无数据时的提示:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity">
<ListView android:id="@+id/listview" android:layout_width="match_parent" android:layout_height="match_parent"/>
<ImageView android:id="@+id/empty_view" android:src="@mipmap/ic_launcher" android:layout_width="match_parent" android:layout_height="match_parent"/>
</FrameLayout>
上面是布局文件
在代码中可以通过以下方式设置emptyView:
listView.setEmptyView(findViewById(R.id.empty_view));
有两种方式来实现滑动监听分别是onTouchListener
和onScrollListener
(1)onTouchListener实现
通过监听onTouchListener中的ACTION_DOWN、ACTION_MOVE、ACTION_UP三个事件来判断滑动状态:
mListView.setOnTouchListener(new View.onTouchListener(){
@Override
public boolean onTouch(View v,MotionEvent event){
String action = event.getAction();
switch(action){
case MotionEvent.ACTION_DOWN:
//触摸时操作
break;
case MotionEvent.ACTION_MOVE:
//移动时操作
break;
case MotionEvent.ACTION_UP:
//离开时操作
break;
default:
break;
}
return true;
}
});
(2)`onScrollListener()`实现
onScrollListener是AbsListView中的监听事件,封装了很多与ListView相关的信息,下面是一般用法:
mListView.setOnScrollListener(new OnScrollListener(){
@Override
public void onScrollStateChanged(AbsListView view,int scrollState){
switch(scrollState){
case OnScrollListener.SCROLL_STATE_IDLE:
//滑动停止时
break;
case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
//正在滑动
break;
case OnScrollListener.SCROLL_STATE_FLING:
//手指抛动时
break;
default:
break;
}
}
@Override
public void onScroll(AbsListView view,int firstVisibleItem,int visibleItemCount,int totalItemCount){
//滚动时调用
if(firstVisibleItem + visibleItemCount == totalItemCount && totalItemCount > 0){
//滑动到最后一行
}
if(firstVisibleItem > lastVisibleItemPosition){
//上滑
}else if(firstVisibleItem < lastVisibleItemPosition){
//下滑
}
}
});