RecyclerView是作为GridView和ListView的后继者添加到android studio的ViewGroup。这是对两者的改进,可以在最新的v-7支持包中找到。创建它的目的是使具有XML布局的任何列表的构造成为可能,并且可以在极大地自定义项目的同时提高ListViews和GridViews的效率。通过回收用户看不见的视图来实现此改进。例如,如果用户向下滚动到可以看到项目4和5的位置,则向下滚动;第1、2和3项将从内存中清除,以减少内存消耗。在本文中,我们将说明如何在android中创建Expandable Recycler View项目。以下是示例视频,展示了我们将要构建的内容。请注意,我们将使用Kotlin语言实施此项目。
分步实施
步骤1:创建一个新项目
要在Android Studio中创建新项目,请参阅如何在Android Studio中创建/启动新项目。请注意,选择Kotlin作为编程语言。
步骤2:添加视图绑定依赖项
转到android标签内的build.gradle(app)和以下依赖项,然后单击立即同步。
buildFeatures {
viewBinding true
}
步骤3:使用activity_main.xml
转到activity_main.xml文件,并参考以下代码。以下是activity_main.xml文件的代码。它只有一个Recycler视图,我们将用它来显示数据。
XML
XML
Kotlin
// this is the Language model class
class Language(
val name : String ="",
val description : String= "",
var expand : Boolean = false
)
Kotlin
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.geeksforgeeks.rvadapterviewbinding.databinding.SingleItemBinding
class RvAdapter(
private var languageList: List
) : RecyclerView.Adapter() {
// create an inner class with name ViewHolder
// It takes a view argument, in which pass the generated class of single_item.xml
// ie SingleItemBinding and in the RecyclerView.ViewHolder(binding.root) pass it like this
inner class ViewHolder(val binding: SingleItemBinding) : RecyclerView.ViewHolder(binding.root)
// inside the onCreateViewHolder inflate the view of SingleItemBinding
// and return new ViewHolder object containing this layout
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val binding = SingleItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return ViewHolder(binding)
}
// bind the items with each item of the list languageList which than will be
// shown in recycler view
// to keep it simple we are not setting any image data to view
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
with(holder){
with(languageList[position]){
// set name of the language from the list
binding.tvLangName.text = this.name
// set description to the text
// since this is inside "expandedView" its visibility will be gone initially
// after click on the item we will make the visibility of the "expandedView" visible
// which will also make the visibility of desc also visible
binding.tvDescription.text = this.description
// check if boolean property "extend" is true or false
// if it is true make the "extendedView" Visible
binding.expandedView.visibility = if (this.expand) View.VISIBLE else View.GONE
// on Click of the item take parent card view in our case
// revert the boolean "expand"
binding.cardLayout.setOnClickListener {
this.expand = !this.expand
notifyDataSetChanged()
}
}
}
}
// return the size of languageList
override fun getItemCount(): Int {
return languageList.size
}
}
Kotlin
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.recyclerview.widget.LinearLayoutManager
import com.geeksforgeeks.rvadapterviewbinding.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
// view binding for the activity
private var _binding: ActivityMainBinding? = null
private val binding get() = _binding!!
// get reference to the adapter class
private var languageList = ArrayList()
private lateinit var rvAdapter: RvAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
_binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
// define layout manager for the Recycler view
binding.rvList.layoutManager = LinearLayoutManager(this)
// attach adapter to the recycler view
rvAdapter = RvAdapter(languageList)
binding.rvList.adapter = rvAdapter
// create new objects
// add some row data
val language1 = Language(
"Java",
"Java is an Object Oriented Programming language." +
" Java is used in all kind of applications like Mobile Applications (Android is Java based), " +
"desktop applications, web applications, client server applications, enterprise applications and many more. ",
false
)
val language2 = Language(
"Kotlin",
"Kotlin is a statically typed, general-purpose programming language" +
" developed by JetBrains, that has built world-class IDEs like IntelliJ IDEA, PhpStorm, Appcode, etc.",
false
)
val language3 = Language(
"Python",
"Python is a high-level, general-purpose and a very popular programming language." +
" Python programming language (latest Python 3) is being used in web development, Machine Learning applications, " +
"along with all cutting edge technology in Software Industry.",
false
)
val language4 = Language(
"CPP",
"C++ is a general purpose programming language and widely used now a days for " +
"competitive programming. It has imperative, object-oriented and generic programming features. ",
false
)
// add items to list
languageList.add(language1)
languageList.add(language2)
languageList.add(language3)
languageList.add(language4)
rvAdapter.notifyDataSetChanged()
}
// on destroy of view make the binding reference to null
override fun onDestroy() {
super.onDestroy()
_binding = null
}
}
步骤4:创建一个新的布局文件并将其命名为single_item.xml文件
转到single_item.xml文件,并参考以下代码。以下是single_item.xml文件的代码。这是我们将在RecyclerView中使用的单个项目布局。
XML格式
步骤5:创建一个新的模型类
创建一个新的Language.kt类,我们将使用自定义通用“ Language ”的数据来传递将在RecyclerView中显示的列表。
科特林
// this is the Language model class
class Language(
val name : String ="",
val description : String= "",
var expand : Boolean = false
)
步骤6:使用适配器类
创建一个新的类RvAdapter.kt,它将充当回收者视图的Adapter类。可扩展回收站视图的逻辑是,首先,我们将ID为“ single_item.xm l”的“ expanded_view ”的布局的可见性更改为GONE ,一旦用户单击任何回收站视图的项目,我们将使其可见性为可见。为了更好的理解,在代码之前添加了注释。
科特林
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.geeksforgeeks.rvadapterviewbinding.databinding.SingleItemBinding
class RvAdapter(
private var languageList: List
) : RecyclerView.Adapter() {
// create an inner class with name ViewHolder
// It takes a view argument, in which pass the generated class of single_item.xml
// ie SingleItemBinding and in the RecyclerView.ViewHolder(binding.root) pass it like this
inner class ViewHolder(val binding: SingleItemBinding) : RecyclerView.ViewHolder(binding.root)
// inside the onCreateViewHolder inflate the view of SingleItemBinding
// and return new ViewHolder object containing this layout
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val binding = SingleItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return ViewHolder(binding)
}
// bind the items with each item of the list languageList which than will be
// shown in recycler view
// to keep it simple we are not setting any image data to view
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
with(holder){
with(languageList[position]){
// set name of the language from the list
binding.tvLangName.text = this.name
// set description to the text
// since this is inside "expandedView" its visibility will be gone initially
// after click on the item we will make the visibility of the "expandedView" visible
// which will also make the visibility of desc also visible
binding.tvDescription.text = this.description
// check if boolean property "extend" is true or false
// if it is true make the "extendedView" Visible
binding.expandedView.visibility = if (this.expand) View.VISIBLE else View.GONE
// on Click of the item take parent card view in our case
// revert the boolean "expand"
binding.cardLayout.setOnClickListener {
this.expand = !this.expand
notifyDataSetChanged()
}
}
}
}
// return the size of languageList
override fun getItemCount(): Int {
return languageList.size
}
}
步骤7:使用MainActivity.kt
转到MainActivity.kt文件,并参考以下代码。下面是MainActivity.kt文件的代码。在代码内部添加了注释,以更详细地了解代码。
科特林
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.recyclerview.widget.LinearLayoutManager
import com.geeksforgeeks.rvadapterviewbinding.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
// view binding for the activity
private var _binding: ActivityMainBinding? = null
private val binding get() = _binding!!
// get reference to the adapter class
private var languageList = ArrayList()
private lateinit var rvAdapter: RvAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
_binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
// define layout manager for the Recycler view
binding.rvList.layoutManager = LinearLayoutManager(this)
// attach adapter to the recycler view
rvAdapter = RvAdapter(languageList)
binding.rvList.adapter = rvAdapter
// create new objects
// add some row data
val language1 = Language(
"Java",
"Java is an Object Oriented Programming language." +
" Java is used in all kind of applications like Mobile Applications (Android is Java based), " +
"desktop applications, web applications, client server applications, enterprise applications and many more. ",
false
)
val language2 = Language(
"Kotlin",
"Kotlin is a statically typed, general-purpose programming language" +
" developed by JetBrains, that has built world-class IDEs like IntelliJ IDEA, PhpStorm, Appcode, etc.",
false
)
val language3 = Language(
"Python",
"Python is a high-level, general-purpose and a very popular programming language." +
" Python programming language (latest Python 3) is being used in web development, Machine Learning applications, " +
"along with all cutting edge technology in Software Industry.",
false
)
val language4 = Language(
"CPP",
"C++ is a general purpose programming language and widely used now a days for " +
"competitive programming. It has imperative, object-oriented and generic programming features. ",
false
)
// add items to list
languageList.add(language1)
languageList.add(language2)
languageList.add(language3)
languageList.add(language4)
rvAdapter.notifyDataSetChanged()
}
// on destroy of view make the binding reference to null
override fun onDestroy() {
super.onDestroy()
_binding = null
}
}
输出:
Github Repo在这里。