我正在尝试使用 recyclerview 在屏幕上打印列表,但适配器部分中的代码不起作用
Posted
技术标签:
【中文标题】我正在尝试使用 recyclerview 在屏幕上打印列表,但适配器部分中的代码不起作用【英文标题】:I'm trying to print a list on the screen using the recyclerview, but the code in the adapter part is not working 【发布时间】:2021-11-18 22:02:18 【问题描述】:MainActivity 如下。 屏幕上什么都没有出现,但我不知道哪一部分是错误的。 如何添加 TV_item_name 的值?
并且在日志中,它来自内部类的 DetailViewAdapter。 Log.d(logTag,onCreateViewHolder11iscaled") 值也没有输出,请问是什么问题?
package com.example.test_recyclerview
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.cardview.widget.CardView
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.test_recyclerview.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity()
private lateinit var binding : ActivityMainBinding
var logTag : String? = "로그 MainActivity"
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
Log.d(logTag,"111 onCreate is called")
binding.mRecyclerView.layoutManager = LinearLayoutManager(this)
val adapter = DetailViewAdapter()
Log.d(logTag,"222 onCreate is called")
binding.mRecyclerView.adapter = adapter
override fun onDestroy()
super.onDestroy()
binding.mRecyclerView.adapter = null
inner class DetailViewAdapter : RecyclerView.Adapter<DetailViewAdapter.ViewHolder>()
private var list = ArrayList<String>()
var logTag : String? = "로그 MainActivity"
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DetailViewAdapter.ViewHolder
Log.d(logTag,"onCreateViewHolder11 is called")
list = getItemList()
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_custom_row, parent, false)
return ViewHolder(view)
override fun onBindViewHolder(holder: ViewHolder, position: Int)
Log.d(logTag,"onBindViewHolder is called")
for (i in 1 until list.size)
Log.d(logTag,"onBindViewHolder is called // list[$i] =" + list[i])
holder.tvItem.text = list[i]
override fun getItemCount(): Int
return list.size
private fun getItemList(): ArrayList<String>
for (i in 1..8)
list.add(i, "Item $i")
return list
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view)
val tvItem : TextView = view.findViewById(R.id.tv_item_name)
val cardViewItem : CardView = view.findViewById(R.id.card_view_item)
item_custom_row.xml
<?xml version="1.0" encoding="utf-8"?>
`enter code here`<LinearLayout 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_
android:layout_>
<androidx.cardview.widget.CardView
android:id="@+id/card_view_item"
android:layout_
android:layout_
android:layout_margin="5dp"
android:padding="10dp"
app:cardCornerRadius="5dp"
app:cardElevation="3dp">
<LinearLayout
android:layout_
android:layout_
android:gravity="center"
android:orientation="horizontal"
tools:ignore="UseCompoundDrawables">
<ImageView
android:layout_
android:layout_
android:contentDescription="@string/app_name"
android:src="@mipmap/ic_launcher" />
<TextView
android:id="@+id/tv_item_name"
android:layout_
android:layout_
android:layout_margin="10dp"
android:textColor="@android:color/black"
android:textSize="18sp"
android:textStyle="bold"
tools:text="Item" />
</LinearLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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_
android:layout_
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/m_RecyclerView"
android:layout_
android:layout_
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
【问题讨论】:
您似乎正在使用数据绑定或视图绑定,但您的视图未包含在问题是您在 onCreateViewHolder
中分配列表,但由于您的 list.size
返回 0,因此不会调用它。
在answer中正确指出
-
在适配器外部创建列表并从构造函数传递它
onBindViewHolder
中的更改实现
以下是您的用例的完整示例:
class MainActivity : AppCompatActivity()
private lateinit var binding: ActivityMainBinding
var logTag: String? = "로그 MainActivity"
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
Log.d(logTag, "111 onCreate is called")
binding.mRecyclerView.layoutManager = LinearLayoutManager(this)
val adapter = DetailViewAdapter(getItemList())
Log.d(logTag, "222 onCreate is called")
binding.mRecyclerView.adapter = adapter
private fun getItemList(): ArrayList<String>
val list = ArrayList<String>()
for (i in 1..8)
list.add("Item $i")
return list
override fun onDestroy()
super.onDestroy()
binding.mRecyclerView.adapter = null
inner class DetailViewAdapter(private val list: ArrayList<String>) :
RecyclerView.Adapter<DetailViewAdapter.ViewHolder>()
var logTag: String? = "로그 MainActivity"
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): DetailViewAdapter.ViewHolder
Log.d(logTag, "onCreateViewHolder11 is called")
val view =
LayoutInflater.from(parent.context).inflate(R.layout.item_custom_row, parent, false)
return ViewHolder(view)
override fun onBindViewHolder(holder: ViewHolder, position: Int)
Log.d(logTag, "onBindViewHolder is called")
holder.tvItem.text = list[position]
override fun getItemCount(): Int
return list.size
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view)
val tvItem: TextView = view.findViewById(R.id.tv_item_name)
val cardViewItem: CardView = view.findViewById(R.id.card_view_item)
【讨论】:
我学会了如何解决问题。答案很有帮助。谢谢你的好意。我还有一个问题。 view.findViewById(R.id.tv_item_name) 可以改成视图绑定吗? @happynewmind 是的,你可以。您只需要将视图持有者行更改为:ViewHolder(rowBinding: ItemCustomRowBinding) : RecyclerView.ViewHolder(rowBinding.root)
和onCreateViewHolder
,您将其更改为return ViewHolder(ItemCustomRowBinding.bind(view))
,之后您应该可以访问您的视图。
非常感谢。你提到的事情执行得很好。【参考方案2】:
从您发布的代码中,我可以看出您的代码存在两个问题。
第一个是您试图从视图持有者内部填充数据列表。会发生以下情况:
-
适配器已创建
适配器想知道它应该创建多少个视图持有者来查看如何填充回收器视图。
适配器调用 getItemCount 并且此方法返回 0,因为列表尚未填充。
没有其他任何东西被调用,因为没有其他东西必须被执行。
所以,要解决这个问题,最简单的方法是让 getItemCount 返回 8 并设置好。但是,解决此问题的更好方法是在适配器之外实例化您的列表,例如在您的活动中,并在初始化适配器时将其作为构造函数参数传递。
我看到的第二个问题是 onBindViewHolder 方法。您正在遍历列表以设置文本,这将导致对于所有项目,您只会将文本设置为最后一项(第 8 项)。您需要记住 onBindViewHolder 是一个在视图持有者需要刷新其内容时调用的方法,因为它将用于显示列表的不同项目,这就是为什么此方法将位置作为参数传递,所以您可以做类似的事情:
holder.tvItem.text = list[position]
** 作为第二个问题的附注,我见过并用来渲染视图持有者内容的更通用方法是创建一个名为“bind”的公共方法,该方法将需要的项目传递给被渲染并在视图持有者上,您将了解如何绘制它的逻辑。比如:
override fun onBindViewHolder(holder: ViewHolder, position: Int)
holder.bind(list[position])
/// Inside the view holder
fun bind(item: String)
tvItem.text = item
【讨论】:
我学会了如何解决问题。答案很有帮助。谢谢你的好意。以上是关于我正在尝试使用 recyclerview 在屏幕上打印列表,但适配器部分中的代码不起作用的主要内容,如果未能解决你的问题,请参考以下文章
浮动操作按钮未显示在 recyclerview 上(位于 DrawerLayout 内)
如何获得 Recyclerview 项目中所有 Edittext 的总和?仅获取屏幕上可见的项目,而不是全部