📌  相关文章
📜  RecyclerView 在 Android 中的多种视图类型与示例

📅  最后修改于: 2022-05-13 01:58:44.777000             🧑  作者: Mango

RecyclerView 在 Android 中的多种视图类型与示例

我们都在 Android 中使用过 RecyclerView 在我们的应用程序中显示列表。 RecyclerView 用于显示 Gmail 应用程序中的电子邮件、Facebook 和 Instagram 上的提要以及 WhatsApp 中的消息等。但是,作为一名 Android 开发人员,您会遇到一个事实,即当我们定义一个视图时,列表项仅根据该视图显示。但是如果你想给 RecyclerView 添加不同的视图类型呢?您可以通过将多个视图添加到同一个 RecyclerView 来实现。本文将教你如何在 RecyclerView 中使用 Multiple Views。

RecyclerView 中的多个视图

一个 RecyclerView 可以包含多个视图。例如,Facebook 上的提要页面就是多视图的一个示例。在同一个 RecyclerView 中,您可以添加图像、视频、文本或三者的组合。在 WhatsApp 上聊天是另一个例子。我们可以认为我们发送的消息被放置在一个 RecyclerView 中。因此,当您发送消息时,它会出现在屏幕的右侧。但是,如果对方发送消息,它会出现在左侧。结果,视图类型发生了变化。这就是我们将在本博客中学习如何做到这一点的方法。我们将创建一个 RecyclerView 并向其添加两个不同的视图。您可以根据您的用例创建更多视图类型。我们首先启动 AndroidStudio 并创建一个新项目:

例子

为项目创建视图

在我们的项目中,我们将使用两个视图,即item_view_1.xmlitem_view_2.xml

XML


  
    
  
    
  


XML


  
    
  
    
  


Kotlin
data class Data(val theView: Int, val theText: String)


Kotlin
class gfgViewAdapter(context: Context, list: ArrayList) :
    RecyclerView.Adapter() {
  
    companion object {
        const val THE_FIRST_VIEW = 1
        const val THE_SECOND_VIEW = 2
    }
  
    private val yourContext: Context = context
    var list: ArrayList = list
  
    private inner class GfgViewOne(itemView: View) :
        RecyclerView.ViewHolder(itemView) {
        var gfgText: TextView = itemView.findViewById(R.id.gfgTextView)
        fun bind(position: Int) {
            val recyclerViewModel = list[position]
            gfgText.text = recyclerViewModel.textData
        }
    }
  
    private inner class View2ViewHolder(itemView: View) :
        RecyclerView.ViewHolder(itemView) {
        var gfgText: TextView = itemView.findViewById(R.id.gfgTextView)
        fun bind(position: Int) {
            val recyclerViewModel = list[position]
            gfgText.text = recyclerViewModel.textData
        }
    }
  
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        if (viewType == VIEW_TYPE_ONE) {
            return GfgViewOne(
                LayoutInflater.from(context).inflate(R.layout.gfgParentOne, parent, false)
            )
        }
        return View2ViewHolder(
            LayoutInflater.from(context).inflate(R.layout.item_view_2, parent, false)
        )
    }
  
    override fun getItemCount(): Int {
        return list.size
    }
  
    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        if (list[position].viewType === VIEW_TYPE_ONE) {
            (holder as GfgViewOne).bind(position)
        } else {
            (holder as View2ViewHolder).bind(position)
        }
    }
  
    override fun getItemViewType(position: Int): Int {
        return list[position].viewType
    }
}


XML


  
    
  


Kotlin
class GeeksforGeeksActivity : AppCompatActivity() {
    private lateinit var gfgRecycler: GfgRecycler
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.gfgMain)
  
        val mydataList = ArrayList()
        dataList.add(Data(GfgRecyclerAdapter.VIEW_TYPE_ONE, "1. Geeks View 1"))
        dataList.add(Data(GfgRecyclerAdapter.VIEW_TYPE_TWO, "2. Geeks View 2"))
        dataList.add(Data(GfgRecyclerAdapter.VIEW_TYPE_ONE, "3. Geeks View 3"))
        dataList.add(Data(GfgRecyclerAdapter.VIEW_TYPE_TWO, "4. Geeks View 4"))
        dataList.add(Data(GfgRecyclerAdapter.VIEW_TYPE_ONE, "5. Geeks View 5"))
        dataList.add(Data(GfgRecyclerAdapter.VIEW_TYPE_TWO, "6. Geeks View 6"))
        dataList.add(Data(GfgRecyclerAdapter.VIEW_TYPE_ONE, "7. Geeks View 7"))
        dataList.add(Data(GfgRecyclerAdapter.VIEW_TYPE_TWO, "8. Geeks View 8"))
        dataList.add(Data(GfgRecyclerAdapter.VIEW_TYPE_ONE, "9. Geeks View 9"))
        dataList.add(Data(GfgRecyclerAdapter.VIEW_TYPE_TWO, "10. Geeks View 10"))
        dataList.add(Data(GfgRecyclerAdapter.VIEW_TYPE_ONE, "11. Geeks View 11"))
        dataList.add(Data(GfgRecyclerAdapter.VIEW_TYPE_TWO, "12. Geeks View 12"))
  
        val adapter = GfgRecyclerAdapter(this, dataList)
        gfgRecycler = findViewById(R.id.gfgRecycler)
        gfgRecycler.layoutManager = LinearLayoutManager(this)
        gfgRecycler.adapter = adapter
    }
}


数据类型

需要一个数据类来存储将在视图上显示的数据。创建一个名为 Data 的数据类并添加以下代码: viewType 指示正在使用哪个视图,项目视图 1 或项目视图 2,textData 存储将在 TextView 上显示的数据。

科特林

data class Data(val theView: Int, val theText: String)

RecyclerView 适配器

现在,对于 RecyclerView,我们必须创建一个 Adapter 类来存储 RecyclerView 的所有逻辑,例如何时显示哪个视图。创建一个 RecyclerViewAdapter 适配器类。在RecyclerViewAdapter类中,如果想要的view是item view 1,就会显示item view 1的内容;否则,将显示项目视图 2 的内容。

科特林

class gfgViewAdapter(context: Context, list: ArrayList) :
    RecyclerView.Adapter() {
  
    companion object {
        const val THE_FIRST_VIEW = 1
        const val THE_SECOND_VIEW = 2
    }
  
    private val yourContext: Context = context
    var list: ArrayList = list
  
    private inner class GfgViewOne(itemView: View) :
        RecyclerView.ViewHolder(itemView) {
        var gfgText: TextView = itemView.findViewById(R.id.gfgTextView)
        fun bind(position: Int) {
            val recyclerViewModel = list[position]
            gfgText.text = recyclerViewModel.textData
        }
    }
  
    private inner class View2ViewHolder(itemView: View) :
        RecyclerView.ViewHolder(itemView) {
        var gfgText: TextView = itemView.findViewById(R.id.gfgTextView)
        fun bind(position: Int) {
            val recyclerViewModel = list[position]
            gfgText.text = recyclerViewModel.textData
        }
    }
  
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        if (viewType == VIEW_TYPE_ONE) {
            return GfgViewOne(
                LayoutInflater.from(context).inflate(R.layout.gfgParentOne, parent, false)
            )
        }
        return View2ViewHolder(
            LayoutInflater.from(context).inflate(R.layout.item_view_2, parent, false)
        )
    }
  
    override fun getItemCount(): Int {
        return list.size
    }
  
    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        if (list[position].viewType === VIEW_TYPE_ONE) {
            (holder as GfgViewOne).bind(position)
        } else {
            (holder as View2ViewHolder).bind(position)
        }
    }
  
    override fun getItemViewType(position: Int): Int {
        return list[position].viewType
    }
}

将 RecyclerView 合并到我们的项目中

现在,在活动 main.xml 文件中,包含 RecyclerView。活动 main.xml 的代码如下:

XML



  
    
  

现在剩下的就是将数据添加到视图中。 MainActivity的代码如下:

科特林

class GeeksforGeeksActivity : AppCompatActivity() {
    private lateinit var gfgRecycler: GfgRecycler
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.gfgMain)
  
        val mydataList = ArrayList()
        dataList.add(Data(GfgRecyclerAdapter.VIEW_TYPE_ONE, "1. Geeks View 1"))
        dataList.add(Data(GfgRecyclerAdapter.VIEW_TYPE_TWO, "2. Geeks View 2"))
        dataList.add(Data(GfgRecyclerAdapter.VIEW_TYPE_ONE, "3. Geeks View 3"))
        dataList.add(Data(GfgRecyclerAdapter.VIEW_TYPE_TWO, "4. Geeks View 4"))
        dataList.add(Data(GfgRecyclerAdapter.VIEW_TYPE_ONE, "5. Geeks View 5"))
        dataList.add(Data(GfgRecyclerAdapter.VIEW_TYPE_TWO, "6. Geeks View 6"))
        dataList.add(Data(GfgRecyclerAdapter.VIEW_TYPE_ONE, "7. Geeks View 7"))
        dataList.add(Data(GfgRecyclerAdapter.VIEW_TYPE_TWO, "8. Geeks View 8"))
        dataList.add(Data(GfgRecyclerAdapter.VIEW_TYPE_ONE, "9. Geeks View 9"))
        dataList.add(Data(GfgRecyclerAdapter.VIEW_TYPE_TWO, "10. Geeks View 10"))
        dataList.add(Data(GfgRecyclerAdapter.VIEW_TYPE_ONE, "11. Geeks View 11"))
        dataList.add(Data(GfgRecyclerAdapter.VIEW_TYPE_TWO, "12. Geeks View 12"))
  
        val adapter = GfgRecyclerAdapter(this, dataList)
        gfgRecycler = findViewById(R.id.gfgRecycler)
        gfgRecycler.layoutManager = LinearLayoutManager(this)
        gfgRecycler.adapter = adapter
    }
}

输出:

现在,当我们运行我们的应用程序时,我们会看到以下屏幕:

图片#1:代码的示意图输出