listview的基本用法大家可能都很熟悉了,下面我总结一些我在工作中对listview的一些使用技巧
1、使用ViewHolder模式来提高效率
我们都知道加载布局的xml文件是很耗时的,为什么呢?因为有许多不同层级的控件,而我们的listview的getview()方法中一般都会通过findviewbyid()去找到某个控件,然后显示,想一想当你在快速滑动一个listview的时候,手机界面上你所能看到的item它都要去加载,所以处理不好就会有卡顿的感觉。而ViewHolder模式就是提高ListView效率的一个很重要的方法,它充分的利用了ListView的视图缓存机制,避免了每次在调用getVIew()方法的时候都去通过findviewbyid()去实例化一个控件,ViewHolder使用起来也很方便,只需要在我们的适配器的类中自定义一个内部类ViewHolder,并将布局中的控件作为成员变量即可。下面是一个简单的ViewHolder的使用:
public class MyAdapter extends BaseAdapter{
private List<UserInfo> list;
private Context context;
private LayoutInflater mInflater;
/**
* 通过构造函数将item的集合传递进来
* @param list
*/
public void Myadapter(List<UserInfo> list,Context context){
this.list = list;
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
/**
* 得到放listview中加入的item的个数。
* 可以在activity中对list初始化,所以可以不在判断list是否为null
*/
@Override
public int getCount() {
return list.size();
}
/**
* 得到对应的item,直接从list中取即可
*/
@Override
public UserInfo getItem(int position) {
return list.get(position);
}
/**
* 也就是每个item对应的索引
*/
@Override
public long getItemId(int position) {
return position;
}
/**
* 这个方法是个关键的方法,用来初始化item并赋值
*/
@Override
public View getView(int position, View view, ViewGroup viewGroup) {
ViewHolder holder = new ViewHolder();
if(view == null){// 第一次不存在,则创建
view = mInflater.inflate(R.layout.item, null);
holder.userName = (TextView) view.findViewById(R.id.user_name);
holder.userNum = (TextView) view.findViewById(R.id.user_num);
holder.userPhone = (ImageView) view.findViewById(R.id.user_phone);
//放入缓存
view.setTag(holder);
}else{//以后每次从缓存中获取
holder = (ViewHolder) view.getTag();
}
UserInfo item = getItem(position);
holder.userName.setText(item.getName());
holder.userNum.setText(item.getNumber());
holder.userPhone.setTextAlignment(item.getImg());
return view;
}
//使用内部类定义布局中需要的控件
static class ViewHolder{
ImageView userPhone;
TextView userName,userNum;
}
}
ListView之间可以通过设置分割线来区分,系统给我们提供了divider和dividerHeighter这2个属性来帮我们实现我们想要的样式,通过这2个属性我们可以设置分割线的颜色,高度,当然也可以是一张图片,代码如下:
android:divider="@android:color/background_dark"
android:dividerHeight="1dp"
3、隐藏ListVIew的滚动条
默认的listview在滚动时,在右边会有一个滚动条,显示当前滑块的位置,我们可以通过设置scrollbars属性来控制是否显示滚动条,隐藏滚动条的代码如下:
android:scrollbars="none"
4、处理空的listview
在我们的项目中有时候会有这样的情况,比如你做的项目有一个用户收藏列表,这个收藏列表你是用listview来实现的,但是在初期用户有可能没有任何收藏,打开这个页面的时候一片空白,感觉不够人性化,你想给用户一个“暂无任何收藏”的提示,那你会怎么做呢?在item.xml布局中放一个textview,然后在adapter中判断是否有数据,如果没有数据就显示一个“暂无任何收藏”的textview,如果有数据就把那个textview设置为隐藏,然后显示正常的收藏数据。其实在listview还有一种更简单的方法来实现这种效果。
listview提供了一个方法,setEmptyView(),通过这个方法,我们可以给listview设置一个空数据下默认的显示。
listview_layout.xml的布局代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ListView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none"
android:divider="@android:color/background_dark"
android:dividerHeight="1dp">
</ListView>
<TextView
android:id="@+id/empty_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="暂无任何数据"/>
</LinearLayout>
在代码中我们通过2行代码设置listview为空是的默认显示。
mlistView = (ListView) findViewById(R.id.list);
mlistView.setEmptyView(findViewById(R.id.empty_tv));
是不是很容易呢。。。
5、遍历listview中的所有item
listview作为一个viewgroup,为我们提供了一个操作子view的方法,最常用的就是getChildAt()来获取一个子view,代码如下:
for(int i=0;i<mlistView.getChildCount();i++){
View view = mlistView.getChildAt(i);
}
6、设置listview需要显示在第几项
listview是以item为一个单元来显示的,默认显示第一个item(索引为0),当需要指定具体显示的item时可以通过以下代码来实现:
mlistView.setSelection(10);
但是这个方法是瞬间完成的移动,除此之外还可以使用以下代码来实现平滑移动
mlistView.smoothScrollBy(distance, duration);
mlistView.smoothScrollByOffset(offset);
mlistView.smoothScrollToPosition(position);