简单(String)
先为ListView 指定一个id,然后将宽度和高度都设置为match_parent,这样ListView 就占满了整个布局的空间。
xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
kt
class MainActivity : AppCompatActivity() {
private val data = listOf("Apple", "Banana", "Orange", "Watermelon", "Pear", "Grape", "Pineapple", "Strawberry", "Cherry", "Mango", "Apple", "Banana", "Orange", "Watermelon", "Pear", "Grape", "Pineapple", "Strawberry", "Cherry", "Mango")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val adapter =
ArrayAdapter<String>(
this, //Activity 的实例
android.R.layout.simple_list_item_1, //ListView 子项布局的id
data //数据源
)
//用ListView 的setAdapter()方法,将构建好的适配器对象传递进去
listView.adapter = adapter
}
}
定制 item(Fruit)
kt
class Fruit(val name:String, val imageId: Int)
xml
<!-- 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>
kt
// FruitAdapter 定义了一个主构造函数:
class FruitAdapter(
activity: Activity, //Activity 的实例
val resourceId: Int, //ListView 子项布局的id
data: List<Fruit> //数据源
) : ArrayAdapter<Fruit>(activity, resourceId, data) {
//重写了getView()方法,这个方法在每个子项被滚动到屏幕内的时候会被调用。
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
//首先,使用LayoutInflater来为这个子项加载我们传入的布局
val view = LayoutInflater.from(context).inflate(resourceId, parent, false)
//接下来,调用View的findViewById()方法,分别获取到ImageView 和TextView 的实例
val fruitImage: ImageView = view.findViewById(R.id.fruitImage)
val fruitName: TextView = view.findViewById(R.id.fruitName)
//然后,通过getItem()方法得到当前项的Fruit实例
val fruit = getItem(position)
//分别调用它们的setImageResource()和setText()方法设置显示的图片和文字
if (fruit != null) {
fruitImage.setImageResource(fruit.imageId)
fruitName.text = fruit.name
}
return view
}
}
kt
class MainActivity : AppCompatActivity() {
private val fruitList = ArrayList<Fruit>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initFruits() // 初始化水果数据
val adapter = FruitAdapter(this, R.layout.fruit_item, fruitList)
listView.adapter = adapter
}
private fun initFruits() {
repeat(2) {
fruitList.add(Fruit("Apple", R.drawable.apple_pic))
fruitList.add(Fruit("Banana", R.drawable.banana_pic))
fruitList.add(Fruit("Orange", R.drawable.orange_pic))
fruitList.add(Fruit("Watermelon", R.drawable.watermelon_pic))
fruitList.add(Fruit("Pear", R.drawable.pear_pic))
fruitList.add(Fruit("Grape", R.drawable.grape_pic))
fruitList.add(Fruit("Pineapple", R.drawable.pineapple_pic))
fruitList.add(Fruit("Strawberry", R.drawable.strawberry_pic))
fruitList.add(Fruit("Cherry", R.drawable.cherry_pic))
fruitList.add(Fruit("Mango", R.drawable.mango_pic))
}
}
}
repeat
函数是Kotlin 中另外一个非常常用的标准函数,它允许你传入一个数值n
,然后会把Lambda 表达式中的内容执行n
遍
提高效率
convertView参数用于将之前加 载好的布局进行缓存,以便之后进行重用:
kt
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
}
...
}
}
继续优化:
kt
class FruitAdapter(activity: Activity, val resourceId: Int, data: List<Fruit>) : ArrayAdapter<Fruit>(activity, resourceId, data) {
//新增了一个内部类ViewHolder,用于对ImageView和TextView的控件实例进行缓存
inner class ViewHolder(val fruitImage: ImageView, val fruitName: TextView)
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)
val fruitImage: ImageView = view.findViewById(R.id.fruitImage)
val fruitName: TextView = view.findViewById(R.id.fruitName)
viewHolder = ViewHolder(fruitImage, fruitName)
//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
}
}