关闭

利用ViewHolder优化BaseAdapter(ListView)

标签: Android学习listview优化BaseAdapter
127人阅读 评论(0) 收藏 举报
分类:

学习http://www.imooc.com/video/7080

有关BaseAdapter的代码及注释笔记

目的:使用ListView列表界面时为了更有效率,下拉等滑动更为平滑,使用一些优化措施。

思路:1.创建Bean对象,用于封装数据

              2.在MyAdapter构造方法中初始化用于映射的数据List

              3.创建ViewHolder类,与布局形成映射。每一个ViewHolder对象就代表一个Item布局

              4.判断convertView是否为空。是则创建并设置tag使之与viewHolder一一对应,否则由tag取出viewHolder

避免多次findViewById寻找控件

              5.给viewHolder中的控件设置数据


代码:

MainActivity:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //创建假数据用于演示
        List<ItemBean> itemBeanList=new ArrayList<>();
        for (int i=0;i<20;i++){
            itemBeanList.add(new ItemBean
                    (R.mipmap.ic_launcher,
                     "我是标题"+i,
                     "我是内容"+i));
        }

        ListView listView=(ListView)findViewById(R.id.lv_main);
        listView.setAdapter(new MyAdapter(this,itemBeanList));
    }


}

ItemBean:

public class ItemBean {
    public int ItemImageResId;
    public String ItemTitle;
    public String ItemContent;

    public ItemBean(int itemImageResId, String itemTitle, String itemContent) {
        ItemImageResId = itemImageResId;
        ItemTitle = itemTitle;
        ItemContent = itemContent;
    }
}


activity_main.xml

<RelativeLayout 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" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <ListView
        android:id="@+id/lv_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </ListView>

</RelativeLayout>


item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <ImageView
        android:id="@+id/iv_image"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:src="@mipmap/ic_launcher" />
    <TextView
        android:id="@+id/tv_title"
        android:layout_width="match_parent"
        android:layout_height="30dp"
        android:layout_toEndOf="@id/iv_image"
        android:layout_toRightOf="@id/iv_image"
        android:text="Title"
        android:gravity="center"
        android:textSize="25sp"/>
    <TextView
        android:id="@+id/tv_content"
        android:layout_width="match_parent"
        android:layout_height="30dp"
        android:layout_toEndOf="@id/iv_image"
        android:layout_toRightOf="@id/iv_image"
        android:layout_below="@id/tv_title"
        android:text="Content"
        android:gravity="center_vertical"
        android:textSize="20sp"/>

</RelativeLayout>

MyAdapter(重点):

public class MyAdapter extends BaseAdapter {

    //映射传进来的数据
    private List<ItemBean> mList;
    private LayoutInflater mInflater;//布局装载器的对象

    public MyAdapter(Context context,List<ItemBean> list){

        mList=list;
        mInflater=LayoutInflater.from(context);
        //确认使用当前的Adapter的界面对象进行布局装载,并对mInflate进行初始化
    }

    /**
     * 适配器的数据集中数据的个数
     * 获取数据量
     * @return
     */
    @Override
    public int getCount() {
        return mList.size();
    }

    /**
     * 获取数据集中指定索引对应的数据项
     * 获取对应ID项对应的Item
     * @param position
     * @return
     */
    @Override
    public Object getItem(int position) {
        return mList.get(position);
    }

    /**
     * 获取指定行对应的ID
     * @param position
     * @return
     */
    @Override
    public long getItemId(int position) {
        return position;
    }

    /**
     * 获取每个Item显示的内容
     * @param position
     * @param convertView
     * @param parent
     * @return
     */
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        /*>>>>>>>>>>逗比式。
        没有任何的优化处理,每次都创建新的View,设置控件。没有根据ListView的缓冲回收机制进行优化
        效率低
        View view=mInflater.inflate(R.layout.item,null);
        ImageView imageView= (ImageView) view.findViewById(R.id.iv_image);
        TextView title=(TextView)view.findViewById(R.id.tv_title);
        TextView content=(TextView)view.findViewById(R.id.tv_content);
        ItemBean bean=mList.get(position);
        imageView.setImageResource(bean.ItemImageResId);
        title.setText(bean.ItemTitle);
        content.setText(bean.ItemContent);
        return view;
        >>>>>>>>>>>>>>>>>>>*/

        /*>>>>>>>>>>>>>>>>>普通式
         使用了convertView,利用了ListView的缓存特性.只有当没有缓存时才会创造新的View,但findViewById仍然会消耗大量时间
        if(convertView==null){
            convertView=mInflater.inflate(R.layout.item,null);
            //如果convertView为空也就是缓冲区为空就导入布局
        }
        ImageView imageView= (ImageView) convertView.findViewById(R.id.iv_image);
        TextView title=(TextView)convertView.findViewById(R.id.tv_title);
        TextView content=(TextView)convertView.findViewById(R.id.tv_content);
        ItemBean bean=mList.get(position);
        imageView.setImageResource(bean.ItemImageResId);
        title.setText(bean.ItemTitle);
        content.setText(bean.ItemContent);
        return convertView;
        >>>>>>>>>>>>>>>>>>>*/

        /*>>>>>>>>>>>>>>>>>文艺式
         总共有两个耗时操作,一个是重复大量地创建convertView或者说View,在普通式中通过判断有无convertView已经避免了
         接下来是另一个findViewById的优化,这就需要ViewHolder*/
         ViewHolder viewHolder;

        if (convertView==null){
            viewHolder=new ViewHolder();
            // 由于我们只需要将XML转化为View,并不涉及到具体的布局,所以第二个参数通常设置为null
            convertView=mInflater.inflate(R.layout.item,null);
            //将findViewById的结果保存到viewHolder对象中
            viewHolder.imageView=(ImageView) convertView.findViewById(R.id.iv_image);
            viewHolder.title=(TextView)convertView.findViewById(R.id.tv_title);
            viewHolder.content=(TextView)convertView.findViewById(R.id.tv_content);
            //关联convertView和viewHolder
            convertView.setTag(viewHolder);
        }else {
            //取出保存的viewHolder对象
            viewHolder=(ViewHolder)convertView.getTag();
        }
        //通过保存在viewHolder中的信息找到控件,避免了多次findViewById来寻找控件
        // 取出bean对象
            ItemBean bean=mList.get(position);
        // 设置控件的数据
            viewHolder.imageView.setImageResource(bean.ItemImageResId);
            viewHolder.title.setText(bean.ItemTitle);
            viewHolder.content.setText(bean.ItemContent);



        return convertView;
    }



    class ViewHolder {
        //避免了重复的findViewById
        // ViewHolder用于缓存控件
        public ImageView imageView;
        public TextView title;
        public TextView content;
    }

}


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:3723次
    • 积分:220
    • 等级:
    • 排名:千里之外
    • 原创:16篇
    • 转载:6篇
    • 译文:0篇
    • 评论:0条