ListView的深入简出的使用2

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进行了一个简单的缓存优化。

发布了18 篇原创文章 · 获赞 2 · 访问量 1494

猜你喜欢

转载自blog.csdn.net/AppWhite_Star/article/details/103500542