对于BaseAdapter相信大家都不陌生,都知道该怎样用、怎样显示数据、怎样尽可能的把每个item做的令自己满意。但问题来了:有些朋友会说我界面做的非常的漂亮,数据也显示的非常完美,但是问什么我的ListView会如此的卡呢?
呵呵,今天我们就来解决这个问题。(关于优化,和解决listview卡的问题)
ListView的绘制机制:当系统开始好绘制ListView的时候,首先会调用getCount()方法(该方法的返回值实际是listview调用AdapterView的getCount()方法得到的)的到其返回值,即ListView的Item个数,返回值是多少就会绘制多少个item(即调用多少次BaseAdapter的getView)。之后系统会调用BaseAdapter的getView方法绘制每一个Item。最后就会在页面上呈现出我们想要的效果。
通过上面的绘制机制我们可以看出:要想对BaseAdapter进行优化实际上优化的是BaseAdapter的getView方法,因为一旦listview开始绘制必定会调用getView方法。
怎么优化呢?
一、一点都没有优化的getView:
@Override public View getView(final int position, View convertView, ViewGroup arg2) { convertView = inflater .inflate(R.layout.p_item, null); Button btn = (Button)convertView.findViewById(R.id.p_item_btn); return convertView; }
上面的getView就是没有做任何处理的getView()此方法在ListView每次绘制的时候都会创建R.layout.p_item布局,并且每次都会创建该布局中的Button按钮。
如果该布局item非常复杂(例如:有几个ImageView和几个button、几个TextView)这就极大的耗费了系统的性能
二、重用主布局item文件:
@Override public View getView(final int position, View convertView, ViewGroup arg2) { if (convertView == null) { convertView = inflater .inflate(R.layout.p_item, null); } Button btn = (Button)convertView.findViewById(R.id.p_item_btn); return convertView; }
我们在创建convertView之前加上一个是否为空的判断,如果为空才创建不为空则不创建,这样就不用每次创建getview的时候都重新创建布局了。对布局重用就好了
(这种方法也是很多朋友一直都使用的方法)
三、重用布局Item,并且重用布局中的控件。
class MyBaseAdapter extends BaseAdapter{ /** * 添加一个内部类来存储Item中的所有有可能使用到的控件 * 充当临时缓存来用 * @author yw-tony * */ class ViewHolder{ Button btn; } private LayoutInflater inflater; private Context context; public MyBaseAdapter(Context context) { inflater = LayoutInflater.from(context); this.context = context; } List<String> ris = new ArrayList<String>(); public void setList(List<String> ris) { this.ris = ris; } @Override public int getCount() { return ris.size(); } @Override public Object getItem(int arg0) { return ris.get(arg0); } @Override public long getItemId(int arg0) { return arg0; } @Override public View getView(final int position, View convertView, ViewGroup arg2) { ViewHolder holder = null;//初始化ViewHolder if (convertView == null) { convertView = inflater .inflate(R.layout.p_item, null); holder = new ViewHolder(); holder.btn = (Button)convertView.findViewById(R.id.p_item_btn); } holder.btn.setText("测试"); return convertView; } }
使用这种方法来处理BaseAdapter会极大的提高baseadapter的性能,因为不仅布局Item重用了,而且item中的控件也重用了。因此在ListView进行绘制的时候时间上getView方法只用初始化布局一次就能够多次使用。非常的节省性能。
好了,本文到此就结束了,希望对大家有所帮助,如果有不同意见欢迎提出来大家共同讨论。