Android RecyclerView

发布时间 2023-06-29 16:39:11作者: Devil'soul

1、用法案例:在RecyclerView中展示水果图片以及水果名称

水果实体类:Fruit.kt

class Fruit(val fruitName: String, val fruitImage: Int)

RecyclerView中水果数据项布局:fruit_item.xml

<?xml version="1.0" encoding="utf-8"?>
<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_gravity="center_vertical"
        android:layout_marginLeft="10dp"
        android:layout_width="40dp"
        android:layout_height="40dp"/>

    <TextView
        android:id="@+id/fruitName"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="10dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</LinearLayout>

适配器Adapter实现:FruitAdapter.kt

class FruitAdapter(private val fruits: List<Fruit>): RecyclerView.Adapter<FruitAdapter.ViewHolder>() {
    
    inner class ViewHolder(view: View): RecyclerView.ViewHolder(view) {
        var fruitImage: ImageView = view.findViewById(R.id.fruitImage)
        var fruitName: TextView = view.findViewById(R.id.fruitName)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        Log.d("FruitAdapter", "onCreateViewHolder ...")
        val view =
            LayoutInflater.from(parent.context).inflate(R.layout.fruit_item, parent, false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        Log.d("FruitAdapter", "onBindViewHolder ...$position")
        holder.fruitImage.setImageResource(fruits[position].fruitImage)
        holder.fruitName.text = fruits[position].fruitName
    }

    override fun getItemCount(): Int {
        return fruits.size
    }
}

这里我们首先定义了一个内部类ViewHolder,它要继承自RecyclerVIew.ViewHolder。然后ViewHolder的主构造函数中要传一个view参数,这个参数就是RecyclerView子项的最外层布局,这样我们就可以通过findViewById来获取布局的元素了

由于FruitAdapter继承RecyclerView.Adapter,那么就必须重写onCreateViewHolder()、onBindViewHolder()以及getItemCount()这三个方法。

onCreateViewHolder方法用来创建ViewHolder实例的,我们在这个方法中将fruit_item.xml布局加载进来,创建ViewHolder实例并返回该实例。

onBindViewHolder方法用于对RecyclerView子项数据进行赋值,会在每个子项被滚进到屏幕内的时候执行,这里通过position参数将对应的水果信息初始化到屏幕内的子项上。

getItemCount方法用于告诉RecyclerView一共有多少个子项,直接返回数据源的长度即可。

这里要说明一点:onCreateViewHolder中创建的组件会被RecyclerView内部机制缓存,当屏幕滚动产生新的子项时,onCreateViewHolder方法不会被执行,RecyclerView内部会使用缓存组件,大大提高了滚动效率。

展示页面逻辑:MainActivity.kt

class MainActivity : AppCompatActivity() {

    private var fruitList = ArrayList<Fruit>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val bind = ActivityMainBinding.inflate(layoutInflater)
        setContentView(bind.root)
        initFruits()
        Log.d("MainActivity", "fruitList: ${fruitList.size}")
        val manager = LinearLayoutManager(this)
        bind.recycleView.layoutManager = manager
        val fruitAdapter = FruitAdapter(fruitList)
        bind.recycleView.adapter = fruitAdapter
    }

    private fun initFruits() {
        repeat(2) {
            fruitList.add(Fruit("apple", R.drawable.fruit))
            fruitList.add(Fruit("pear", R.drawable.fruit))
            fruitList.add(Fruit("banana", R.drawable.fruit))
            fruitList.add(Fruit("orange", R.drawable.fruit))
            fruitList.add(Fruit("peach", R.drawable.fruit))
            fruitList.add(Fruit("nectarine", R.drawable.fruit))
            fruitList.add(Fruit("apricot", R.drawable.fruit))
            fruitList.add(Fruit("plum", R.drawable.fruit))
            fruitList.add(Fruit("prune", R.drawable.fruit))
            fruitList.add(Fruit("persimmon", R.drawable.fruit))
            fruitList.add(Fruit("lemon", R.drawable.fruit))
            fruitList.add(Fruit("grape", R.drawable.fruit))
            fruitList.add(Fruit("watermelon", R.drawable.fruit))
            fruitList.add(Fruit("pineapple", R.drawable.fruit))
            fruitList.add(Fruit("blueberry", R.drawable.fruit))
            fruitList.add(Fruit("strawberry", R.drawable.fruit))
            fruitList.add(Fruit("waxberry", R.drawable.fruit))
            fruitList.add(Fruit("mulberry", R.drawable.fruit))
            fruitList.add(Fruit("cherrytomato", R.drawable.fruit))
        }
    }
}

自定义一个水果数组用来提供FruitAdater数据。

LinearLayoutManager用于指定RecyclerView的布局方式,这里是线性布局。一定要设置布局方式,不然RecyclerView不起作用,无法显示。

接着初始化FruitAdapter并适配到RecyclerView。