<span style="font-size:24px;">listview是一个很重要的控件,如果真正的想熟悉使用listview也不太容易,虽然项目中很多使用到,而且也做出来了,但并对他十分的了解,还有item和它子控件的点击事件,加载图片时出现的各种问题,今天就讲讲listview的优化,一般在显示很多条目时会使用listview,而listview显示那么多条目时,在屏幕上都是一个个view对象,如果显示1000条数据,那么就要创建1000个view对象,这肯定太消耗内存,那肯定是做了缓存,我们在listview的adapter中有一个getView()方法,这方法中第二个参数convertView就是缓存起来的对象,</span>
新建一个android项目listview,
MainActivity.java
<span style="font-size:24px;">public class MainActivity extends Activity { private List<String> datas; private LayoutInflater inflater; private Context context; private MyAdapter adapter; private ListView listview; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); inflater = LayoutInflater.from(this); context = MainActivity.this; listview = (ListView) findViewById(R.id.listview); initData(); adapter= new MyAdapter(); listview.setAdapter(adapter); } private void initData() { datas = new ArrayList<String>(); for(int i=0;i<50;i++){ datas.add("测试"+":::::::"+i); } } class MyAdapter extends BaseAdapter{ @Override public int getCount() { return datas.size(); } @Override public Object getItem(int position) { return datas.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup arg2) { View view; <span style="white-space:pre"> </span>view = inflater.inflate(R.layout.item, null); <span style="white-space:pre"> </span>TextView tvContent = (TextView) view.findViewById(R.id.tvContent); <span style="white-space:pre"> </span>ImageView img = (ImageView) view.findViewById(R.id.img); <span style="white-space:pre"> </span>tvContent.setText(datas.get(position)); <span style="white-space:pre"> </span>ImgTask imgTask = new ImgTask(img); <span style="white-space:pre"> </span>imgTask.execute(imgUrls.get(position)); <span style="white-space:pre"> </span>return view; } } }</span>
这样虽然listview能把数据展示出来,但我们仔细想想,如果我们要展示1000条甚至1万条数据时,getView()方法返回的view对象就要创建1万个view对象,那么对内存是多大的开销和浪费,google这样级别的公司肯定是做了优化的,之前说了在getView()方法中第二个参数converView,这就是缓存起来的view对象,那么这个converView是指哪个对象呢?
converView是指当listview滑动出屏幕的时候,而且至少有一个item完全的滑出屏幕时,
那么这个完全滑出屏幕的view就缓存到了内存,就赋值给了converView,这个时候converView对象就不为你null了,现在getView()方法换个写法
View view; if(convertView==null){ view = inflater.inflate(R.layout.item, null); }else{ view = convertView; } TextView tvContent = (TextView) view.findViewById(R.id.tvContent); ImageView img = (ImageView) view.findViewById(R.id.img); tvContent.setText(datas.get(position)); ImgTask imgTask = new ImgTask(img); imgTask.execute(imgUrls.get(position)); return view;
其实就几行代码,我们发现每次通过view去findViewById()也是浪费时间的,因此我们希望把寻找的id封装起来,在java中封装熟悉肯定是用类封装,那我们就现在用类去封装寻找到的控件id,顺便提一句,id是和view绑定在一起的,因此view也是要存在起来的,先看代码
@Override public View getView(int position, View convertView, ViewGroup arg2) { ViewHolder viewHolder = null; if(convertView==null){ viewHolder = new ViewHolder(); convertView = inflater.inflate(R.layout.item, null); viewHolder.tvContent = (TextView) convertView.findViewById(R.id.tvContent); viewHolder.img = (ImageView) convertView.findViewById(R.id.img); convertView.setTag(viewHolder); }else{ viewHolder = (ViewHolder) convertView.getTag(); } viewHolder.tvContent.setText(datas.get(position)); ImgTask imgTask = new ImgTask(viewHolder.img); imgTask.execute(imgUrls.get(position)); return convertView; } class ViewHolder{ TextView tvContent; ImageView img; } }
listview优化讲到此为止!