Android ListView/gridView代码优化ViewHolder,converView使用

来源:互联网 发布:linux怎么禁ping 编辑:程序博客网 时间:2024/06/05 18:46

BaseAdapter 代码

public class ListViewAdapter extends BaseAdapter {    Context context;    List<ListViewItem> list;// 传过来的数据    public int getCount() {        return list==null?0:list.size();    }    public ListViewAdapter(Context context, List<ListViewItem> list) {        super();        this.context = context;        this.list = list;    }    public Object getItem(int position) {        return null;    }    public long getItemId(int position) {        return 0;    }    public View getView(int position, View convertView, ViewGroup parent) {        Holder holder;        //如果convertView为空就创建一个View,否则使用getTag缓存的View        if (convertView == null) {            holder = new Holder();            convertView = LayoutInflater.from(context).inflate(R.layout.listview_item, null);            holder.title = (TextView) convertView.findViewById(R.id.tv_title);            holder.text = (TextView) convertView.findViewById(R.id.tv_text);            convertView.setTag(holder);        } else {            holder = (Holder) convertView.getTag();        }        // 设置item的标题,文本        holder.title.setText(list.get(position).title);        holder.text.setText(list.get(position).text);        return convertView;    }    class Holder {        TextView title;        TextView text;    }}

简要说明

  • getView方法是 ListView 或者 gridView 获取 View 的代码。
  • ListView 是根据getCount返回的值来确定行数的。getCount返回0就不显示。
  • 当我们列表项多的时候也就意味着 ListView需要显示的View变多,如果我们不对View复用的,那么每加载一个新的列表项,LayoutInflater.inflate就会调用一次就会生成一个新的View。

这会让我们的程序卡顿,滑动多了还会out of memory

如下图,很明显的显示了convertView的作用,当ListView里面的列表项被移出屏幕后,会缓存最后一次移出的View,在下一次getView的时候作为参数传递。也就是一个ListView不论有多小列表项,adapter一共就就持有屏幕上所能显示的列表项数量。

这里写图片描述

代码分析

  • 当converView==null,也就是屏幕上还没铺满item时,我们就inflate的列表项布局文件生成View,及findView布局文件里面的View 并且创建holder
  • 这个Holder的属性是我们需要加载的列表项的子View,用来保存子View的引用,避免再次findView。
  • View.setTag(Holder)用于保存Holder的引用。也就是保存子View的引用(View的Tag属性,可携带对象和键 - 值对)

MainActivity

public class MainActivity extends Activity {    private List<ListViewItem> dataList = new ArrayList<>();// listView 使用的数据    private ListView listView;    private ListViewAdapter listViewAdapter;// listView 数据的适配器    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        findView();// 获取组件        loadData();// 加载数据        listView.setAdapter(listViewAdapter);// 设置适配器---传入context---传入数据    }    private void findView() {        listView = (ListView) findViewById(R.id.list_view);        listViewAdapter = new ListViewAdapter(this, dataList);    }    // 加载数据项    private void loadData() {        for (int i = 0; i < 1000; i++) {            dataList.add(new ListViewItem("Title:   " + i, "*********************"));        }    }}

——————————丝般柔顺——————————————

0 0
原创粉丝点击