使用RecyclerView显示文字列表

使用RecyclerView显示文字列表

1. 创建和使用RecyclerView

在刚接触RecyclerView的时候,我寻思着这不就是一个和ListView一样的UI组件吗,直接再MainActivety里操作还不行吗。看我暴力拖动:

RecyclerView的确出现了,但是还差不少意思,因为我想要显示的文字列表并不非那莪简单就能实现

这就体现了代码的重要性了,抛去想当然,如果想要使RecylerView成功显示,需要搞清四个部分

列表项:哪些数据需要我们去显示?

Adapter:如何获取这些数据?(适配器)

ViewHolder:把这些数据放哪儿(一个个视图池)

RecyclerView:最终显示给用户的样子

接着,我们就逐个击破,在击破之前,还需要切换一下布局。我们常用的布局是ConstraintLayout,在放置多个子视图的时候用它再合适不过了,但是我们只有一个RecyclerView子视图,用它似乎就有些冗余,不如使用简单的FrameLayout FrameLayout的代码块如下,将它复制到activity_main.xml中

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
​
</FrameLayout>

2.列表项

这一部分很容易理解,就是准备数据 首先在res>values>strings中添加列表数据:

创建一个DataSource.kt,在里面调用你的数据列表

package com.example.affirmations.data
​
import com.example.affirmations.R
import com.example.affirmations.model.Affirmation
​
class Datasource {
    fun loadAffirmations(): List<Affirmation>{
        return  listOf<Affirmation>(
            Affirmation(R.string.affirmation1),
            Affirmation(R.string.affirmation2),
            Affirmation(R.string.affirmation3),
            Affirmation(R.string.affirmation4),
            Affirmation(R.string.affirmation5),
            Affirmation(R.string.affirmation6),
            Affirmation(R.string.affirmation7),
            Affirmation(R.string.affirmation8),
            Affirmation(R.string.affirmation9),
            Affirmation(R.string.affirmation10)
        )
​
    }
}

3.RecyclerView

这是最容易击破的了,就是开局的暴力拖动,当然也可以直接在FrameLayout中添加代码

<androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layoutManager="LinearLayoutManager"
        android:scrollbars="vertical"
        />

4.Adapter以及ViewHolder

这一部分就不太容易了,慢慢来。 首先,RecyclerView中的每一个列表项都有自己的布局,为了定义每一个布局,我们可以在单独的布局文件中定义这些布局。 所以先在 res > layout 中,新建名为 list_item.xml 的空 File;在 Code 视图中打开 list_item.xml;添加 id 为 item_title 的 TextView;针对 layout_width 和 layout_height 添加 wrap_content,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/item_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="TextView" />

接着,创建一个ItemAdapter类:

ItemAdapter需要获取文字列表以及有关如何解析字符串资源信息,文字列表好办,向里面传一个列表就完事儿了,那么解析字符串资源的信息从哪里来呢?其实这些信息和有关·应用的信息都被存储在了context中,所以context也要被传进去。如下:

class ItemAdapter(private val context: Context, private val dataset: List<Affirmation>) {

}

紧接着,需要创建一个ViewHolder RecyclerView不会直接和列表项试图交互,而是处理ViewHolder。啥是VeiwHolder?一个ViewHolder代表RecyclerView中的一个列表项视图,可以根据需要重复使用。 So,继续在ItemAdapter中创建一个嵌套类(不强制嵌套类哈~这里代表ItemViewHOlder仅由ItemAdapter使用,有助于别人了解你的程序结构):

class ItemAdapter(
    private val context: Context,
    private val dataset: List<Affirmation>
) : RecyclerView.Adapter<ItemAdapter.ItemViewHolder>() {

    class ItemViewHolder(private val view: View) : RecyclerView.ViewHolder(view) {
        val textView: TextView = view.findViewById(R.id.item_title)
    }
}

代码仍然会报错,因为ItemAdapter这里继承了一个父类,这个父类是一个抽象类,所以我们需要完成这个函数的所有功能 将鼠标转移到ItemAdapter上,按ctrl+l,有三个方法出现了: getItemCount():列表中有多少个元素要显示?即后续要多少个ViewHolder onCreateViewHolder():创建ViewHolder onBindViewHolder():

全部OK一下,会出现以下代码:

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder {
    TODO("Not yet implemented")
}
​
override fun getItemCount(): Int {
    TODO("Not yet implemented")
}
​
override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
    TODO("Not yet implemented")
}

所以,我们仍然需要逐个击破一下。 首先解决getItemCount()

//得知数据集的大小
override fun getItemCount(): Int {
    return dataset.size
}

然后实现onCreateViewHolder(),这一个方法将被布局管理器调用,为RecyclerView创建新的ViewHolder

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder {
    // 创建一个新视图
    val adapterLayout = LayoutInflater.from(parent.context)
        .inflate(R.layout.list_item, parent, false)
​
    return ItemViewHolder(adapterLayout)
}

最后一个了,实现以下onBindViewHolder(),这个方法也是由布局管理器调用,用来替换列表项视图里的内容。

override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
    val item = dataset[position]
    holder.textView.text =  context.resources.getString(item.stringResourceId)
}

最终的ItemAdapter.kt代码如下:

package com.example.affirmations.adapter
​
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.example.affirmations.R
import com.example.affirmations.model.Affirmation
​
class ItemAdapter(private val context: Context, private val dataset: List<Affirmation>): RecyclerView.Adapter<ItemAdapter.ItemViewHolder>(){
    class ItemViewHolder(private val view:View): RecyclerView.ViewHolder(view){
        val textView: TextView = view.findViewById(R.id.item_title)
​
    }//嵌套类
​
    //由布局管理器调用
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder {
        val adapterLayout = LayoutInflater.from(parent.context).inflate(R.layout.list_item, parent, false) //存储着对视图的引用
        return ItemViewHolder(adapterLayout)
    }
​
    //返回数据集的大小
    //override fun getItemCount() = dataset.size
    override fun getItemCount(): Int {
        return dataset.size
    }
    override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
        holder.textView.text = context.getString(dataset[position].stringResourceId)
    }
​
}

5.修改MainActivity以使用RecyclerView

最后,就需要用MainActivity去调用你刚刚创建的类和方法了。 具体代码如下:

package com.example.affirmations
​
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.example.affirmations.adapter.ItemAdapter
import com.example.affirmations.data.Datasource
​
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
​
        //将Datasource实例化,调用其中的loadAffirmations方法
        val myDataset = Datasource().loadAffirmations()
        var recyclerView = findViewById<RecyclerView>(R.id.recycler_view)
​
        recyclerView.adapter = ItemAdapter(this,myDataset)
​
        recyclerView.setHasFixedSize(true)
    }
}

最终的效果如下:

 详细代码已上传

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值