ListView的深入简出的使用2
ListView如何添加事件监听与两重优化
ListView的点击事件
1. ListView第一种添加事件的方式:
可以直接给item这一行加,也可以直接给item中的某一个组件加,这里演示给item添加点击事件。
//这里的view 是
//适配器中getView中代表每一行视图的view
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String packageName = appNames.get(i).activityInfo.packageName;
String classString = appNames.get(i).activityInfo.name;
ComponentName componentName = new ComponentName(packageName,classString);
Intent intent = new Intent();
intent.setComponent(componentName);
startActivity(intent);
}
});
2. ListView的第二种添加事件的方式
给整个listview容器添加item的点击事件:
ListView main_list_view = findViewById(R.id.main_list_view);
//得到所有应用数据传入Adapter 为listView设置适配器
main_list_view.setAdapter(new MyAdapter(getAppInfos()));
main_list_view.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
String packageName = appNames.get(i).activityInfo.packageName;
String classString = appNames.get(i).activityInfo.name;
ComponentName componentName = new ComponentName(packageName,classString);
Intent intent = new Intent();
intent.setComponent(componentName);
startActivity(intent);
}
});
以上就大概讲了一下listview 的如何添加事件。
下面开始讲一个非常重要的话题
listview的优化
当listview的item很多的时候,滑动就会产生卡顿。所以我们要对此进行处理。
listview 每次滑动一次view都会重新加载绘制一次
(通过LayoutInflate加载布局,找到视图组件,设置数据)
每一次getView()被调用都会执行以上步骤!!所以会执行很多次。
这样就会像我上面说的数据一多,滑动时就会非常卡顿.
通过研究 我们发现listview可以有一个复用机制
复用机制采用的是:
一屏幕的item数量+1 当上面的item消失了就会到最底下
于是乎我们在view为空的时候才去加载它:
但是我们发现虽然 view 是实现了复用,但是每次 getView() 时,都要对每个子 View 中包含的控件进行实例化(findViewById)操作,这也是一个耗时的操作,这里就使用到了 ViewHolder 这个类来进行优化操作(把每一条数据进行缓存,其实也不一定要叫viewholder,叫什么都可以,只是大家都这么写所以形成了一个规范)。
定义一个ViewHolder类,里面的成员变量为你listview中item中的组件类型,一一对应。
public class ViewHolder{
//里面的成员变量就是有什么item组件 一一对应
private ImageView app_image;
private TextView app_name;
}
并且让view 和 viewHolder产生关联setTag(),让viewHolder保存已经创建出来的视图。
ViewHolder viewHolder = new ViewHolder();
if(view == null){
view = LayoutInflater.from(MainActivity.this).inflate(R.layout.item_app_list,null);
//读取布局的视图 通过view 并把视图给viewHolder保存
viewHolder.app_image = view.findViewById(R.id.app_image);
viewHolder.app_name =view.findViewById(R.id.app_name);
view.setTag(viewHolder);//让view 和 viewHolder进行关联
}else{
viewHolder = (ViewHolder) view.getTag();//不为空直接复用
}
如果已经不为空了,ViewHolder此时已经有视图对象了,我们直接取出来用就好了,这样子视图就复用了原来的还保存有了视图对象
接下来我们只需要清洗数据,替换成我们自己要的数据就好,也是直接VieHolder点赋值就可以了,因为它拥有了视图对象,正如我上面所说。
viewHolder.app_name.setText(appNames.get(i).activityInfo.loadLabel(getPackageManager()));
viewHolder.app_image.setImageDrawable(appNames.get(i).activityInfo.loadIcon(getPackageManager()));
这样我们就对ListView进行了一个简单的缓存优化。