ListView优化,和getView方法的研究

来源:互联网 发布:linux 服务启动脚本 编辑:程序博客网 时间:2024/04/30 14:16

public abstract View getView (int position, View convertView, ViewGroup parent)

Added in API level 1

Get a View that displays the data at the specified position in the data set. You can either create a View manually or inflate it from an XML layout file. When the View is inflated, the parent View (GridView, ListView...) will apply default layout parameters unless you use inflate(int, android.view.ViewGroup, boolean) to specify a root view and to prevent attachment to the root.

Parameters
position The position of the item within the adapter's data set of the item whose view we want.convertView The old view to reuse, if possible. Note: You should check that this view is non-null and of an appropriate type before using. If it is not possible to convert this view to display the correct data, this method can create a new view. Heterogeneous lists can specify their number of view types, so that this View is always of the right type (see getViewTypeCount() and getItemViewType(int)).parentThe parent that this view will eventually be attached to
Returns
  • A View corresponding to the data at the specified position.
上面是google的API ,对getView()的解释读起来还是挺清晰的,不过就是少了点延伸。
今天在读取数据和数据显示到listview上的时候遇到了很多问题,首先得问题是 listView的优化,和bordercastreceiver 的发送接收问题。

在网上很多博客看到,listview可以用viewHolder这个东西进行优化,还有利用getView()方法里的convertView进行判断优化。看了一下代码,感觉写的和所讲的有很多出入,很多干扰人的地方,读起来一头雾水,不过还是有很多值得借鉴的地方。在一番搜索和阅读之后,自己终于理清楚了这个东西的应用。
//ViewHolder静态类    static class ViewHolder    {        public ImageView img;        public TextView title;        public TextView info;    }        public class MyAdapter extends BaseAdapter    {            private LayoutInflater mInflater = null;        private MyAdapter(Context context)        {            //根据context上下文加载布局,这里的是Demo17Activity本身,即this            this.mInflater = LayoutInflater.from(context);        }        @Override        public int getCount() {            //How many items are in the data set represented by this Adapter.            //在此适配器中所代表的数据集中的条目数            return data.size();        }        @Override        public Object getItem(int position) {            // Get the data item associated with the specified position in the data set.            //获取数据集中与指定索引对应的数据项            return position;        }        @Override        public long getItemId(int position) {            //Get the row id associated with the specified position in the list.            //获取在列表中与指定索引对应的行id            return position;        }                //Get a View that displays the data at the specified position in the data set.        //获取一个在数据集中指定索引的视图来显示数据        @Override        public View getView(int position, View convertView, ViewGroup parent) {            ViewHolder holder = null;            //如果缓存convertView为空,则需要创建View            if(convertView == null)            {                holder = new ViewHolder();                //根据自定义的Item布局加载布局                convertView = mInflater.inflate(R.layout.list_item, null);                holder.img = (ImageView)convertView.findViewById(R.id.img);                holder.title = (TextView)convertView.findViewById(R.id.tv);                holder.info = (TextView)convertView.findViewById(R.id.info);                //将设置好的布局保存到缓存中,并将其设置在Tag里,以便后面方便取出Tag                convertView.setTag(holder);            }else            {                holder = (ViewHolder)convertView.getTag();            }            holder.img.setBackgroundResource((Integer)data.get(position).get("img"));            holder.title.setText((String)data.get(position).get("title"));            holder.info.setText((String)data.get(position).get("info"));                        return convertView;        }            }



下面是两个关键点,和各自的作用:

convertView的作用在于复用在用户视野外的listView的行来加载当前视野中的行,可以减少UI的绘制消耗,大大优化了用户体验。

ViewHolder的作用在于,将listView的每一行的控件元素绑定在行上面,这样每次在复用convertView的时候就不用再一次的 findviewbyid 去寻找,减少了开销。

listView的优化目前我自己从网上了解的方法就是这二者,从ViewHolder的应用我自己发现其实可以有一种变种的ViewHolder的用法。
看到这一行
convertView = mInflater.inflate(R.layout.list_item, null);
我将这个LayoutInflater 
换成一个自定义的linearLayout,然后将findviewbyid这个过程放到linearLayout里,然后在这个类中写一个载入数据的公共方法,之后就可以在getView()中调用,复用listview行的同时也起到了viewholder的作用,因为在构造函数中我执行了findviewbyid这个过程,载入输入时就可以直接拿出来用。而且这样做之后代码量少了,逻辑也更清晰。

public View getView(int position, View convertView, ViewGroup arg2) {        if (subject_list == null) {return null;}        if(convertView == null){            //首次加载默认控件            convertView = new OneView(mContext);        }        OneView newView = (OneSubjectView)convertView;        newView.updateView(subject_list.get(position)); //加载数据方法         convertView = newView;return convertView;}





0 0
原创粉丝点击