android listview优化

来源:互联网 发布:盛世网络剧 编辑:程序博客网 时间:2024/05/13 22:30

<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;@Overrideprotected 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{@Overridepublic int getCount() {return datas.size();}@Overridepublic Object getItem(int position) {return datas.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic 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对象只有当converView对象为null时创建,根据之前讲的,view最多创建的个数,应该是当前listview可见条目的个数或者可见条目的个数+1个,而通过view.findViewById()的一些控件,因为view对象不同而不同,这点一定要知道,因为这会涉及到listview异步加载图片发生错乱等寻找原因的证明,既然优化了view对象创建的次数,是不是代表这个写的很完美,不能再优化了呢?,答案是no,


其实就几行代码,我们发现每次通过view去findViewById()也是浪费时间的,因此我们希望把寻找的id封装起来,在java中封装熟悉肯定是用类封装,那我们就现在用类去封装寻找到的控件id,顺便提一句,id是和view绑定在一起的,因此view也是要存在起来的,先看代码


@Overridepublic 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;}}

现在发现只有当converView对象为null时,才去加载view,并findViewById(),当converView不为null时,id直接从ViewHolder对象中取就不必要每次都去findViewById(),又是优化了一点点,ViewHolder对象创建的个数和View对象创建个数一样,也就是说创建了多少个View对象就创建了多少个ViewHolder对象,


listview优化讲到此为止!




0 0
原创粉丝点击