1.convertView优化快速滚动效率
getView()中有一个名为convertView的参数,其用于将之前加载好的布局进行缓存,以便重用。上代码,
@Override public View getView(int position, View convertView, ViewGroup parent){ Fruit fruit = getItem(position); //获取当前项的Fruit实例 /*原方法,View view = LayoutInflater.from(getContext()).inflate(resourceId, null);*/ /*使用convertView */ View view; if (convertView == null){ view = LayoutInflater.from(getContext().inflate(resourceId, null)); } else{ view = convertView; } ImageView fruitImage = (ImageView) view.findViewById(R.id.fruit_image); TextView fruitName = (TextView) view.findViewById(R.id.fruit_name); fruitImage.setImageResource(fruit.getImageId()); fruitName.setText(fruit.getName()); return view; }
如代码注释,注释内的为原方法,每次getView都需要将布局重新加载一遍,当ListView快速滚动时会有性能障碍。
使用convertView方法后,首先判断convertView是否为空,若为空,使用LayoutInflater来加载布局;若不为空,直接对convertView进行重用。
LOL
2.ViewHolder对控件实例进行缓存
还是如上的代码中,我们发现,每次在getView()方法中都会调用view中的findViewById来获取一次控件的实例。
该ViewHolder闪亮登场了,直接上代码,
@Override public View getView(int position, View convertView, ViewGroup parent){ Fruit fruit = getItem(position); //获取当前项的Fruit实例 /*原方法,View view = LayoutInflater.from(getContext()).inflate(resourceId, null); */ /*原方法, ImageView fruitImage = (ImageView) view.findViewById(R.id.fruit_image); TextView fruitName = (TextView) view.findViewById(R.id.fruit_name); fruitImage.setImageResource(fruit.getImageId()); fruitName.setText(fruit.getName());*/ viewHolder.fruitImage.setImageResource(fruit.getImageId()); viewHolder.fruitName.setText(fruit.getName()); //使用convertView View view; ViewHolder viewHolder; if (convertView == null){ view = LayoutInflater.from(getContext()).inflate(resourceId, null); //将ViewHolder存储在View中 viewHolder = new viewHolder(); viewHolder.fruitImage = (ImageView) view.findViewById(R.id.fruit_image); viewHolder.fruitName = (TextView) view.findViewById(R.id.fruit_name); view.setTag(viewHolder); /*将ViewHolder存储在View中*/ } else{ view = convertView; viewHolder = (ViewHolder) view.getTag(); //重新获取ViewHolder } return view; } class ViewHolder{ ImageView fruitImage; TextView fruitName; }
注意看新增的部分。
新建了一个内部类ViewHolder,用于对控件的实例进行缓存。
若convertView为空,创建ViewHolder对象,并将所有控件的实例都存在ViewHolder中,接着调用view的setTag()方法,将ViewHolder对象存放在view中;
若convertView不为空,调用view的getTag()方法,将ViewHolder重新取出。
因此,所有的控件实例都缓存在了ViewHolder中,不必如原方法般每次都通过findViewById来依次获取控件实例,从而优化了性能。么么哒。
LOL
没有评论:
发表评论