基本用法
ListView 需要:数据 ListData、子项及其布局,这些都在 Adapter 中处理。
// 数据 ListData
fruitList.add(Fruit("Apple", R.drawable.apple_pic)) ...
// 子项类
class Fruit(val name:String, val imageId: Int)
<!-- 子项布局:fruit_item.xml -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="60dp">
<ImageView
android:id="@+id/fruitImage"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"/>
<TextView
android:id="@+id/fruitName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp" />
</LinearLayout>
val adapter = FruitAdapter(
this,
R.layout.fruit_item,
fruitList
)
class FruitAdapter(
activity: Activity,
val resourceId: Int,
data: List<Fruit>
) : ArrayAdapter<Fruit>(activity, resourceId, data) {
// getView():子项被滚动到屏幕内的时候被调用。
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
// 载入子项布局
val view = LayoutInflater.from(context).inflate(resourceId, parent, false)
val fruitImage: ImageView = view.findViewById(R.id.fruitImage)
val fruitName: TextView = view.findViewById(R.id.fruitName)
// getItem():获得子项数据,从 ListData 中
val fruit = getItem(position)
// 结合子项数据和子项布局
if (fruit != null) {
fruitImage.setImageResource(fruit.imageId)
fruitName.text = fruit.name
}
return view
}
}
listView.adapter = adapter
提高效率
convertView
缓存住滑出屏幕的View。
class FruitAdapter(activity: Activity, val resourceId: Int, data: List<Fruit>) : ArrayAdapter<Fruit>(activity, resourceId, data) {
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val view: View
if (convertView == null) {
view = LayoutInflater.from(context).inflate(resourceId, parent, false)
} else {
view = convertView
}
...
}
}
继续优化:内部类 ViewHolder
缓存 子项View内具体组件。
class FruitAdapter(activity: Activity, val resourceId: Int, data: List<Fruit>) : ArrayAdapter<Fruit>(activity, resourceId, data) {
inner class ViewHolder(val view: View) {
val fruitImage: ImageView
val fruitName: TextView
init {
fruitImage = view.findViewById(R.id.fruitImage)
fruitName = view.findViewById(R.id.fruitName)
}
}
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val view: View
val viewHolder: ViewHolder
if (convertView == null) {
view = LayoutInflater.from(context).inflate(resourceId, parent, false)
viewHolder = ViewHolder(view)
// View.setTag():将 ViewHolder 对象存储在View中
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
}
}