上篇介绍了ListView的用法,链接如下,这篇主要讲解如何提升ListView的效率
Android 定制ListView的界面
1、使用缓存布局
ListView如果不进行优化,其运行效率是很低的,因为在Adapter类的getView方法中,每次都将布局重新加载一遍,当ListView快速滚动时,这就会成为性能瓶颈。
Adapter类的getView方法有一个参数:View convertView,这个参数用于将之前加载好的布局进行缓存,以便之后进行重用,我们可以借助这个参数进行性能优化。
class FruitAdapter(activity: Activity, private val resourceId: Int, data: List<Fruit>): ArrayAdapter<Fruit>(activity, resourceId, data) { override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { Log.d("FruitAdapter", "convertView: $convertView ") val view = convertView ?: LayoutInflater.from(context).inflate(resourceId, parent, false) val imageView = view.findViewById<ImageView>(R.id.fruitImage) val fruitName: TextView = view.findViewById(R.id.fruitName) val fruit = getItem(position) if (fruit != null) { imageView.setImageResource(fruit.imageId) fruitName.text = fruit.name Log.d("FruitAdapter", "name: ${fruit.name} position: $position") } return view } }
其中标红的代码就是优化后的逻辑。如果convertView 为空,则使用LayoutInflater去加载布局,如果不为空,则直接对convertView进行重用。这样就大大提高了ListView的运行效率,在快速滚动的时候可以表现出更好的性能。
2、使用ViewHolder优化findViewById
虽然现在不会重复加载布局,但是每次在getView方法中仍然会调用View的findViewById()方法来重复获取控件的实例。这也是比较消耗性能的操作。
对此我们可以使用ViewHolder来对这部分性能进行优化。
class FruitAdapter(activity: Activity, private val resourceId: Int, data: List<Fruit>): ArrayAdapter<Fruit>(activity, resourceId, data) { inner class ViewHolder(val fruitImage: ImageView, val fruitName: TextView) override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { Log.d("FruitAdapter", "convertView: $convertView ") val view: View val viewHolder: ViewHolder if (convertView == null) { view = LayoutInflater.from(context).inflate(resourceId, parent, false) val imageView = view.findViewById<ImageView>(R.id.fruitImage) val fruitName: TextView = view.findViewById(R.id.fruitName) viewHolder = ViewHolder(imageView, fruitName) view.tag = viewHolder } else { view = convertView viewHolder = view.tag as ViewHolder } val fruit = getItem(position) if (fruit != null) { viewHolder.fruitImage.setImageResource(fruit.imageId) viewHolder.fruitName.text = fruit.name } return view } }
我们新增了一个内部类ViewHolder,用于对ImageView和TextView的控件实例进行缓存(Kotlin中使用inner class关键字来定义内部类)。
使用View的setTag()方法来对ViewHolder进行保存,这样在缓存存在的情况下,没有必要每次通过findViewById来获取控件实例了。
通过这两步优化后,ListView的运行效率就已经非常不错了。
标签:val,fruitName,fruit,convertView,Android,ListView,效率,view From: https://www.cnblogs.com/shibin90/p/17512070.html