如何在 Android RecyclerView 中添加分隔线?
在 Kotlin 中的 Android RecyclerView 一文中,演示了如何在 Android 中实现 RecyclerView。但是在用户体验的情况下,需要通过每个项目中的分隔符和适当的填充和边距来区分项目。在这种情况下, RecyclerView ItemDecoration 出现在画面中。因此,在此演示了如何实际使用 RecyclerView ItemDecoration 并在 RecyclerView Items 之间使用分隔线和自定义分隔线。查看下图以了解整个讨论的概况。
创建一个空的活动项目
要在 Android Studio 中创建新项目,请参阅如何在 Android Studio 中创建/启动新项目。
添加所需的依赖
在build.gradle文件中包含 google material design components 依赖项。添加依赖项后,不要忘记单击右上角的“立即同步”按钮。
implementation “androidx.recyclerview:recyclerview:1.2.1”
请注意,在同步项目时,您需要连接到网络,并确保将依赖项添加到应用级 Gradle文件中,如下所示。
在RecyclerView中实现Item Decoration的步骤
步骤 1:使用 activity_main.xml 文件
该项目的主要布局包含一个 RecyclerView 用于演示目的。要实现相同的调用,请在 activity_main.xml 文件中调用以下代码。
XML
XML
Kotlin
data class RecyclerViewData(
val text1: String,
val text2: String
)
Kotlin
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
class MyRecyclerViewAdapter(private val items: List) :
RecyclerView.Adapter() {
inner class MyRecyclerViewDataHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyRecyclerViewDataHolder {
val view: View =
LayoutInflater.from(parent.context).inflate(R.layout.recycler_data_view, parent, false)
return MyRecyclerViewDataHolder(view)
}
override fun onBindViewHolder(holder: MyRecyclerViewDataHolder, position: Int) {
val currentItem: RecyclerViewData = items[position]
val tvNumber: TextView = holder.itemView.findViewById(R.id.tvNumber)
tvNumber.text = currentItem.text1
val tvNumbersInText: TextView = holder.itemView.findViewById(R.id.tvNumbersInText)
tvNumbersInText.text = currentItem.text2
}
override fun getItemCount(): Int {
return items.size
}
}
Kotlin
package com.adityamshidlyali.gfgautohidefab
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// create instance of RecyclerView
// and register with the appropriate ID
val recyclerView: RecyclerView = findViewById(R.id.recyclerView)
// create list of RecyclerViewData
var recyclerViewData = listOf()
recyclerViewData = recyclerViewData + RecyclerViewData("1", "One")
recyclerViewData = recyclerViewData + RecyclerViewData("2", "Two")
recyclerViewData = recyclerViewData + RecyclerViewData("3", "Three")
recyclerViewData = recyclerViewData + RecyclerViewData("4", "Four")
recyclerViewData = recyclerViewData + RecyclerViewData("5", "Five")
recyclerViewData = recyclerViewData + RecyclerViewData("6", "Six")
recyclerViewData = recyclerViewData + RecyclerViewData("7", "Seven")
recyclerViewData = recyclerViewData + RecyclerViewData("8", "Eight")
recyclerViewData = recyclerViewData + RecyclerViewData("9", "Nine")
recyclerViewData = recyclerViewData + RecyclerViewData("10", "Ten")
recyclerViewData = recyclerViewData + RecyclerViewData("11", "Eleven")
recyclerViewData = recyclerViewData + RecyclerViewData("12", "Twelve")
recyclerViewData = recyclerViewData + RecyclerViewData("13", "Thirteen")
recyclerViewData = recyclerViewData + RecyclerViewData("14", "Fourteen")
recyclerViewData = recyclerViewData + RecyclerViewData("15", "Fifteen")
// create a vertical layout manager
val layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
// create instance of MyRecyclerViewAdapter
val myRecyclerViewAdapter = MyRecyclerViewAdapter(recyclerViewData)
// attach the adapter to the recycler view
recyclerView.adapter = myRecyclerViewAdapter
// also attach the layout manager
recyclerView.layoutManager = layoutManager
// make the adapter the data set
// changed for the recycler view
myRecyclerViewAdapter.notifyDataSetChanged()
}
}
Kotlin
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// create instance of RecyclerView and register with the appropriate ID
val recyclerView: RecyclerView = findViewById(R.id.recyclerView)
// create list of RecyclerViewData
var recyclerViewData = listOf()
recyclerViewData = recyclerViewData + RecyclerViewData("1", "One")
recyclerViewData = recyclerViewData + RecyclerViewData("2", "Two")
recyclerViewData = recyclerViewData + RecyclerViewData("3", "Three")
recyclerViewData = recyclerViewData + RecyclerViewData("4", "Four")
recyclerViewData = recyclerViewData + RecyclerViewData("5", "Five")
recyclerViewData = recyclerViewData + RecyclerViewData("6", "Six")
recyclerViewData = recyclerViewData + RecyclerViewData("7", "Seven")
recyclerViewData = recyclerViewData + RecyclerViewData("8", "Eight")
recyclerViewData = recyclerViewData + RecyclerViewData("9", "Nine")
recyclerViewData = recyclerViewData + RecyclerViewData("10", "Ten")
recyclerViewData = recyclerViewData + RecyclerViewData("11", "Eleven")
recyclerViewData = recyclerViewData + RecyclerViewData("12", "Twelve")
recyclerViewData = recyclerViewData + RecyclerViewData("13", "Thirteen")
recyclerViewData = recyclerViewData + RecyclerViewData("14", "Fourteen")
recyclerViewData = recyclerViewData + RecyclerViewData("15", "Fifteen")
// create a vertical layout manager
val layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
// create instance of MyRecyclerViewAdapter
val myRecyclerViewAdapter = MyRecyclerViewAdapter(recyclerViewData)
// attach the adapter to the recycler view
recyclerView.adapter = myRecyclerViewAdapter
// also attach the layout manager
recyclerView.layoutManager = layoutManager
// call the method addItemDecoration with the
// recyclerView instance and add default Item Divider
recyclerView.addItemDecoration(
DividerItemDecoration(
baseContext,
layoutManager.orientation
)
)
// make the adapter the data set
// changed for the recycler view
myRecyclerViewAdapter.notifyDataSetChanged()
}
}
XML
Kotlin
import android.content.Context
import android.graphics.Canvas
import android.graphics.drawable.Drawable
import android.view.View
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
class RecyclerViewItemDecoration(
context: Context,
resId: Int
) : RecyclerView.ItemDecoration() {
private var mDivider: Drawable = ContextCompat.getDrawable(context, resId)!!
override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
super.onDraw(c, parent, state)
// left margin for the divider
val dividerLeft: Int = 32
// right margin for the divider with
// reference to the parent width
val dividerRight: Int = parent.width - 32
// this loop creates the top and bottom
// divider for each items in the RV
// as each items are different
for (i in 0 until parent.childCount) {
// this condition is because the last
// and the first items in the RV have
// no dividers in the list
if (i != parent.childCount - 1) {
val child: View = parent.getChildAt(i)
val params = child.layoutParams as RecyclerView.LayoutParams
// calculating the distance of the
// divider to be drawn from the top
val dividerTop: Int = child.bottom + params.bottomMargin
val dividerBottom: Int = dividerTop + mDivider.intrinsicHeight
mDivider.setBounds(dividerLeft, dividerTop, dividerRight, dividerBottom)
mDivider.draw(c)
}
}
}
}
Kotlin
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// create instance of RecyclerView and register with the appropriate ID
val recyclerView: RecyclerView = findViewById(R.id.recyclerView)
// create list of RecyclerViewData
var recyclerViewData = listOf()
recyclerViewData = recyclerViewData + RecyclerViewData("1", "One")
recyclerViewData = recyclerViewData + RecyclerViewData("2", "Two")
recyclerViewData = recyclerViewData + RecyclerViewData("3", "Three")
recyclerViewData = recyclerViewData + RecyclerViewData("4", "Four")
recyclerViewData = recyclerViewData + RecyclerViewData("5", "Five")
recyclerViewData = recyclerViewData + RecyclerViewData("6", "Six")
recyclerViewData = recyclerViewData + RecyclerViewData("7", "Seven")
recyclerViewData = recyclerViewData + RecyclerViewData("8", "Eight")
recyclerViewData = recyclerViewData + RecyclerViewData("9", "Nine")
recyclerViewData = recyclerViewData + RecyclerViewData("10", "Ten")
recyclerViewData = recyclerViewData + RecyclerViewData("11", "Eleven")
recyclerViewData = recyclerViewData + RecyclerViewData("12", "Twelve")
recyclerViewData = recyclerViewData + RecyclerViewData("13", "Thirteen")
recyclerViewData = recyclerViewData + RecyclerViewData("14", "Fourteen")
recyclerViewData = recyclerViewData + RecyclerViewData("15", "Fifteen")
// create a vertical layout manager
val layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
// create instance of MyRecyclerViewAdapter
val myRecyclerViewAdapter = MyRecyclerViewAdapter(recyclerViewData)
// attach the adapter to the recycler view
recyclerView.adapter = myRecyclerViewAdapter
// also attach the layout manager
recyclerView.layoutManager = layoutManager
// call the method addItemDecoration with the
// recyclerView instance and pass custom ItemDecoration instance
recyclerView.addItemDecoration(RecyclerViewItemDecoration(this, R.drawable.divider))
// make the adapter the data set changed
// for the recycler view
myRecyclerViewAdapter.notifyDataSetChanged()
}
}
在进入输出之前,我们需要用数据填充 RecyclerView。所以我们现在需要使用 RecyclerView Adapter 和 RecyclerView 的自定义视图。
第 2 步:为 RecyclerView 创建自定义视图
RecyclerView 的自定义视图在左侧包含一个简单的图标和两个 TextView。要实现相同的功能,请在布局文件夹中创建一个名为recycler_data_view.xml的文件并调用以下代码。
XML
上面的自定义视图为列表中的每个项目生成以下输出:
第 3 步:为 RecyclerView 创建数据类
现在通过使用以下代码创建数据类来为上述自定义视图创建数据。
科特林
data class RecyclerViewData(
val text1: String,
val text2: String
)
第 4 步:创建 RecyclerView 适配器
以下代码需要通过创建名为 MyRecyclerAdapter 的类在单独的类中调用。
科特林
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
class MyRecyclerViewAdapter(private val items: List) :
RecyclerView.Adapter() {
inner class MyRecyclerViewDataHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyRecyclerViewDataHolder {
val view: View =
LayoutInflater.from(parent.context).inflate(R.layout.recycler_data_view, parent, false)
return MyRecyclerViewDataHolder(view)
}
override fun onBindViewHolder(holder: MyRecyclerViewDataHolder, position: Int) {
val currentItem: RecyclerViewData = items[position]
val tvNumber: TextView = holder.itemView.findViewById(R.id.tvNumber)
tvNumber.text = currentItem.text1
val tvNumbersInText: TextView = holder.itemView.findViewById(R.id.tvNumbersInText)
tvNumbersInText.text = currentItem.text2
}
override fun getItemCount(): Int {
return items.size
}
}
步骤 5:使用 MainActivity.kt 文件
在这个类中,我们必须以列表的形式为 RecyclerView 创建一些示例数据。要实现相同的调用,请在 MainActivity.kt 文件中调用以下代码(添加注释以便更好地理解)。
科特林
package com.adityamshidlyali.gfgautohidefab
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// create instance of RecyclerView
// and register with the appropriate ID
val recyclerView: RecyclerView = findViewById(R.id.recyclerView)
// create list of RecyclerViewData
var recyclerViewData = listOf()
recyclerViewData = recyclerViewData + RecyclerViewData("1", "One")
recyclerViewData = recyclerViewData + RecyclerViewData("2", "Two")
recyclerViewData = recyclerViewData + RecyclerViewData("3", "Three")
recyclerViewData = recyclerViewData + RecyclerViewData("4", "Four")
recyclerViewData = recyclerViewData + RecyclerViewData("5", "Five")
recyclerViewData = recyclerViewData + RecyclerViewData("6", "Six")
recyclerViewData = recyclerViewData + RecyclerViewData("7", "Seven")
recyclerViewData = recyclerViewData + RecyclerViewData("8", "Eight")
recyclerViewData = recyclerViewData + RecyclerViewData("9", "Nine")
recyclerViewData = recyclerViewData + RecyclerViewData("10", "Ten")
recyclerViewData = recyclerViewData + RecyclerViewData("11", "Eleven")
recyclerViewData = recyclerViewData + RecyclerViewData("12", "Twelve")
recyclerViewData = recyclerViewData + RecyclerViewData("13", "Thirteen")
recyclerViewData = recyclerViewData + RecyclerViewData("14", "Fourteen")
recyclerViewData = recyclerViewData + RecyclerViewData("15", "Fifteen")
// create a vertical layout manager
val layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
// create instance of MyRecyclerViewAdapter
val myRecyclerViewAdapter = MyRecyclerViewAdapter(recyclerViewData)
// attach the adapter to the recycler view
recyclerView.adapter = myRecyclerViewAdapter
// also attach the layout manager
recyclerView.layoutManager = layoutManager
// make the adapter the data set
// changed for the recycler view
myRecyclerViewAdapter.notifyDataSetChanged()
}
}
输出:
在 RecyclerView 中为项目创建默认分隔线
我们必须使用带有 RecyclerView 实例的addItemDecoration()方法创建一个默认的 Divider,我们需要传递ItemDecoration (在本例中为DividerItemDecoration() )实例和LayoutManager的方向(在本例中为垂直)回收者视图。要实现相同的调用 MainActivity.kt 文件中的以下代码(添加注释以便更好地理解)。
科特林
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// create instance of RecyclerView and register with the appropriate ID
val recyclerView: RecyclerView = findViewById(R.id.recyclerView)
// create list of RecyclerViewData
var recyclerViewData = listOf()
recyclerViewData = recyclerViewData + RecyclerViewData("1", "One")
recyclerViewData = recyclerViewData + RecyclerViewData("2", "Two")
recyclerViewData = recyclerViewData + RecyclerViewData("3", "Three")
recyclerViewData = recyclerViewData + RecyclerViewData("4", "Four")
recyclerViewData = recyclerViewData + RecyclerViewData("5", "Five")
recyclerViewData = recyclerViewData + RecyclerViewData("6", "Six")
recyclerViewData = recyclerViewData + RecyclerViewData("7", "Seven")
recyclerViewData = recyclerViewData + RecyclerViewData("8", "Eight")
recyclerViewData = recyclerViewData + RecyclerViewData("9", "Nine")
recyclerViewData = recyclerViewData + RecyclerViewData("10", "Ten")
recyclerViewData = recyclerViewData + RecyclerViewData("11", "Eleven")
recyclerViewData = recyclerViewData + RecyclerViewData("12", "Twelve")
recyclerViewData = recyclerViewData + RecyclerViewData("13", "Thirteen")
recyclerViewData = recyclerViewData + RecyclerViewData("14", "Fourteen")
recyclerViewData = recyclerViewData + RecyclerViewData("15", "Fifteen")
// create a vertical layout manager
val layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
// create instance of MyRecyclerViewAdapter
val myRecyclerViewAdapter = MyRecyclerViewAdapter(recyclerViewData)
// attach the adapter to the recycler view
recyclerView.adapter = myRecyclerViewAdapter
// also attach the layout manager
recyclerView.layoutManager = layoutManager
// call the method addItemDecoration with the
// recyclerView instance and add default Item Divider
recyclerView.addItemDecoration(
DividerItemDecoration(
baseContext,
layoutManager.orientation
)
)
// make the adapter the data set
// changed for the recycler view
myRecyclerViewAdapter.notifyDataSetChanged()
}
}
输出:
现在为 RecyclerView 项目创建自定义分隔线
如果分隔线需要自定义,则需要在 drawable 文件夹中创建我们自己的形状。所以这里的形状是一个矩形,高度为 2dp,颜色为绿色。要实现相同的形状,请在divider.xml 文件中调用以下代码并在drawable 文件夹中创建此文件。
XML
现在我们需要创建我们自己的 ItemDecoration 类并覆盖onDraw()方法。这个方法被调用一次,这个方法决定了需要在何处绘制分隔线以及如何绘制。这里的一个主要重要事项是不要为第一项和最后一项添加分隔符。要实现相同的调用 RecyclerViewItemDecoration.kt 文件中的以下代码(添加注释以更好地理解)。
科特林
import android.content.Context
import android.graphics.Canvas
import android.graphics.drawable.Drawable
import android.view.View
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
class RecyclerViewItemDecoration(
context: Context,
resId: Int
) : RecyclerView.ItemDecoration() {
private var mDivider: Drawable = ContextCompat.getDrawable(context, resId)!!
override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
super.onDraw(c, parent, state)
// left margin for the divider
val dividerLeft: Int = 32
// right margin for the divider with
// reference to the parent width
val dividerRight: Int = parent.width - 32
// this loop creates the top and bottom
// divider for each items in the RV
// as each items are different
for (i in 0 until parent.childCount) {
// this condition is because the last
// and the first items in the RV have
// no dividers in the list
if (i != parent.childCount - 1) {
val child: View = parent.getChildAt(i)
val params = child.layoutParams as RecyclerView.LayoutParams
// calculating the distance of the
// divider to be drawn from the top
val dividerTop: Int = child.bottom + params.bottomMargin
val dividerBottom: Int = dividerTop + mDivider.intrinsicHeight
mDivider.setBounds(dividerLeft, dividerTop, dividerRight, dividerBottom)
mDivider.draw(c)
}
}
}
}
现在,这个自定义 ItemDecoration 需要附加到回收器视图。所以现在使用 MainActivity.kt 文件,我们需要在其中传递自定义 ItemDecoration 类的实例(在本例中为 RecyclerViewItemDecoration)。要实现相同的调用,请在 MainActivity.kt 文件中调用以下代码。
科特林
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// create instance of RecyclerView and register with the appropriate ID
val recyclerView: RecyclerView = findViewById(R.id.recyclerView)
// create list of RecyclerViewData
var recyclerViewData = listOf()
recyclerViewData = recyclerViewData + RecyclerViewData("1", "One")
recyclerViewData = recyclerViewData + RecyclerViewData("2", "Two")
recyclerViewData = recyclerViewData + RecyclerViewData("3", "Three")
recyclerViewData = recyclerViewData + RecyclerViewData("4", "Four")
recyclerViewData = recyclerViewData + RecyclerViewData("5", "Five")
recyclerViewData = recyclerViewData + RecyclerViewData("6", "Six")
recyclerViewData = recyclerViewData + RecyclerViewData("7", "Seven")
recyclerViewData = recyclerViewData + RecyclerViewData("8", "Eight")
recyclerViewData = recyclerViewData + RecyclerViewData("9", "Nine")
recyclerViewData = recyclerViewData + RecyclerViewData("10", "Ten")
recyclerViewData = recyclerViewData + RecyclerViewData("11", "Eleven")
recyclerViewData = recyclerViewData + RecyclerViewData("12", "Twelve")
recyclerViewData = recyclerViewData + RecyclerViewData("13", "Thirteen")
recyclerViewData = recyclerViewData + RecyclerViewData("14", "Fourteen")
recyclerViewData = recyclerViewData + RecyclerViewData("15", "Fifteen")
// create a vertical layout manager
val layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
// create instance of MyRecyclerViewAdapter
val myRecyclerViewAdapter = MyRecyclerViewAdapter(recyclerViewData)
// attach the adapter to the recycler view
recyclerView.adapter = myRecyclerViewAdapter
// also attach the layout manager
recyclerView.layoutManager = layoutManager
// call the method addItemDecoration with the
// recyclerView instance and pass custom ItemDecoration instance
recyclerView.addItemDecoration(RecyclerViewItemDecoration(this, R.drawable.divider))
// make the adapter the data set changed
// for the recycler view
myRecyclerViewAdapter.notifyDataSetChanged()
}
}
输出: