在回收站视图中滚动时数据消失
Data disappears when scrolling in recycler view
美好的一天。所以我目前在我的回收站视图中有数据。它现在只是静态数据。我仍然需要在我导入的地方做代码。然而,我的问题是我有一个按钮可以更改文本视图的背景。这发生在我的适配器中。当我滚动浏览我的列表时,bg 颜色变化会恢复到单击按钮之前的状态。我已经阅读了很多类似的问题,但无法真正找到一个解释清楚或对我有用的问题。根据我的阅读,数据被重置为静态数据,因为它当前正在我的 onBindViewHolder 中发生,我认为这会更改每次读取(滚动)新数据时的数据。我读到我应该创建一个 link 或一个监听器,然后调用它。但这对我来说没有意义,因为如果 link 被调用的次数与代码执行的次数相同,那么它将是相同的,不是吗。也许有一个条件侦听器,但不确定这是否可行。
我对 android 和科特林有些陌生。现在已经使用它一个月了。我不知道我在做什么,但我得到了最后期限。很遗憾没有时间去学习基础知识。感谢您提供的所有帮助。如果您需要任何额外的 code/information
,请告诉我
我的适配器
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RowViewHolder {
val itemView = LayoutInflater.from(parent.context).inflate(R.layout.table_list_item, parent, false)
return RowViewHolder(itemView)
}
private fun setHeaderBg(view: View) {
view.setBackgroundResource(R.drawable.table_header_cell_bg)
}
private fun setContentBg(view: View) {
view.setBackgroundResource(R.drawable.table_content_cell_bg)
}
override fun onBindViewHolder(holder: RowViewHolder, position: Int) {
// (TableViewAdapter.DataviewHolder) .bind()
val rowPos = holder.adapterPosition
if (rowPos == 0) {
// Header Cells. Main Headings appear here
holder.itemView.apply {
setHeaderBg(txtWOrder)
setHeaderBg(txtDElNote)
setHeaderBg(txtCompany)
// setHeaderBg(txtAddress)
setHeaderBg(txtWeight)
setHeaderBg(txtbutton1)
setHeaderBg(txtbutton2)
setHeaderBg(txttvdone)
txtWOrder.text = "WOrder"
txtDElNote.text = "DElNote"
txtCompany.text = "Company"
// txtAddress.text = "Address"
txtWeight.text = "Weight"
txtbutton1.text = "Delivered"
txtbutton2.text = "Exception"
txttvdone.text = ""
}
} else {
val modal = Tripsheetlist[rowPos - 1]
holder.itemView.apply {
setContentBg(txtWOrder)
setContentBg(txtDElNote)
setContentBg(txtCompany)
// setContentBg(txtAddress)
setContentBg(txtWeight)
setContentBg(txtbutton1)
setContentBg(txtbutton2)
setContentBg(txttvdone)
txtWOrder.text = modal.WOrder.toString()
txtDElNote.text = modal.DElNote.toString()
txtCompany.text = modal.Company.toString()
// txtAddress.text = modal.Address.toString()
txtWeight.text = modal.Weight.toString()
txtbutton1.text = modal.Button1.toString()
txtbutton2.text = modal.Button2.toString()
txttvdone.text = modal.tvdone.toString()
}
}
holder.apply {
txtbutton1.setOnClickListener {
Log.e("Clicked", "Successful delivery")
txttvdone.setBackgroundResource(R.color.green)
txttvdone.setText("✓")
}
txtbutton2.setOnClickListener {
Log.e("Clicked", "Exception on delivery")
txttvdone.setBackgroundResource(R.color.orange)
txttvdone.setText("x")
}
}
}
class RowViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
val txttvdone:TextView = itemView.findViewById<TextView>(R.id.txttvdone)
val txtbutton1:Button = itemView.findViewById<Button>(R.id.txtbutton1)
val txtbutton2:Button = itemView.findViewById<Button>(R.id.txtbutton2)
} class MyViewHolder(val view: View) : RecyclerView.ViewHolder(view){
var txtbutton1 = view.findViewById<Button>(R.id.txtbutton1)
val txtbutton2:Button = itemView.findViewById<Button>(R.id.txtbutton2)
var txttvdone = view.findViewById<TextView>(R.id.txttvdone)
}
我试过 (TableViewAdapter.DataviewHolder) .bind() 这样做并创建另一个 class 正如我看到的那样是在另一个线程中完成的 () 这很像我的问题.我似乎无法实施他的解决方案来使我的工作正常进行。 (没有完全理解他的解决方案)
//我也知道我正在使用将在年底到期的 android 扩展。但现在它可以工作,一旦我准备好代码并且 运行 我将开始转向更新版本的 kotlin。
顾名思义,RecyclerView 将在视图离开屏幕时回收视图。这意味着当一个项目的视图进入视图时,它会被重新创建并调用 onBindViewHolder()
来填充详细信息。
您的适配器内的 onClickListener
更改了单元格视图的其中一个子视图的背景。但是,如果该单元格离开屏幕并返回,它将被重新绘制。
为了解决这个问题,您的 onClickListener 应该更改数据项上的 属性,并且您的 onBindViewHolder
应该检查 属性 以确定要显示的背景颜色子视图:
enum class DataState {
Unselected,
Success,
Failure
}
data class DataItem(var state: DataState = DataState.Unselected)
class MyAdapter : RecyclerView.Adapter<MyViewHolder>() {
var dataItems: List<DataItem> = emptyList()
fun updateData(data: List<DataItem>) {
dataItems = data
notifyDataSetChanged()
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val dataItem = dataItems[position]
holder.txttvdone.apply {
setBackgroundResource(when (dataItem.state) {
DataState.Unselected -> android.R.color.transparent
DataState.Success -> R.color.green
DataState.Failure -> R.color.orange
})
text = when (dataItem.state) {
DataState.Unselected -> ""
DataState.Success -> "✓"
DataState.Failure -> "x"
}
}
holder.apply {
txtbutton1.setOnClickListener {
Log.e("Clicked", "Successful delivery")
dataItem.state = DataState.Success
notifyDataSetChanged()
}
txtbutton2.setOnClickListener {
Log.e("Clicked", "Exception on delivery")
dataItem.state = DataState.Failure
notifyDataSetChanged()
}
}
}
}
美好的一天。所以我目前在我的回收站视图中有数据。它现在只是静态数据。我仍然需要在我导入的地方做代码。然而,我的问题是我有一个按钮可以更改文本视图的背景。这发生在我的适配器中。当我滚动浏览我的列表时,bg 颜色变化会恢复到单击按钮之前的状态。我已经阅读了很多类似的问题,但无法真正找到一个解释清楚或对我有用的问题。根据我的阅读,数据被重置为静态数据,因为它当前正在我的 onBindViewHolder 中发生,我认为这会更改每次读取(滚动)新数据时的数据。我读到我应该创建一个 link 或一个监听器,然后调用它。但这对我来说没有意义,因为如果 link 被调用的次数与代码执行的次数相同,那么它将是相同的,不是吗。也许有一个条件侦听器,但不确定这是否可行。
我对 android 和科特林有些陌生。现在已经使用它一个月了。我不知道我在做什么,但我得到了最后期限。很遗憾没有时间去学习基础知识。感谢您提供的所有帮助。如果您需要任何额外的 code/information
,请告诉我我的适配器
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RowViewHolder {
val itemView = LayoutInflater.from(parent.context).inflate(R.layout.table_list_item, parent, false)
return RowViewHolder(itemView)
}
private fun setHeaderBg(view: View) {
view.setBackgroundResource(R.drawable.table_header_cell_bg)
}
private fun setContentBg(view: View) {
view.setBackgroundResource(R.drawable.table_content_cell_bg)
}
override fun onBindViewHolder(holder: RowViewHolder, position: Int) {
// (TableViewAdapter.DataviewHolder) .bind()
val rowPos = holder.adapterPosition
if (rowPos == 0) {
// Header Cells. Main Headings appear here
holder.itemView.apply {
setHeaderBg(txtWOrder)
setHeaderBg(txtDElNote)
setHeaderBg(txtCompany)
// setHeaderBg(txtAddress)
setHeaderBg(txtWeight)
setHeaderBg(txtbutton1)
setHeaderBg(txtbutton2)
setHeaderBg(txttvdone)
txtWOrder.text = "WOrder"
txtDElNote.text = "DElNote"
txtCompany.text = "Company"
// txtAddress.text = "Address"
txtWeight.text = "Weight"
txtbutton1.text = "Delivered"
txtbutton2.text = "Exception"
txttvdone.text = ""
}
} else {
val modal = Tripsheetlist[rowPos - 1]
holder.itemView.apply {
setContentBg(txtWOrder)
setContentBg(txtDElNote)
setContentBg(txtCompany)
// setContentBg(txtAddress)
setContentBg(txtWeight)
setContentBg(txtbutton1)
setContentBg(txtbutton2)
setContentBg(txttvdone)
txtWOrder.text = modal.WOrder.toString()
txtDElNote.text = modal.DElNote.toString()
txtCompany.text = modal.Company.toString()
// txtAddress.text = modal.Address.toString()
txtWeight.text = modal.Weight.toString()
txtbutton1.text = modal.Button1.toString()
txtbutton2.text = modal.Button2.toString()
txttvdone.text = modal.tvdone.toString()
}
}
holder.apply {
txtbutton1.setOnClickListener {
Log.e("Clicked", "Successful delivery")
txttvdone.setBackgroundResource(R.color.green)
txttvdone.setText("✓")
}
txtbutton2.setOnClickListener {
Log.e("Clicked", "Exception on delivery")
txttvdone.setBackgroundResource(R.color.orange)
txttvdone.setText("x")
}
}
}
class RowViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
val txttvdone:TextView = itemView.findViewById<TextView>(R.id.txttvdone)
val txtbutton1:Button = itemView.findViewById<Button>(R.id.txtbutton1)
val txtbutton2:Button = itemView.findViewById<Button>(R.id.txtbutton2)
} class MyViewHolder(val view: View) : RecyclerView.ViewHolder(view){
var txtbutton1 = view.findViewById<Button>(R.id.txtbutton1)
val txtbutton2:Button = itemView.findViewById<Button>(R.id.txtbutton2)
var txttvdone = view.findViewById<TextView>(R.id.txttvdone)
}
我试过 (TableViewAdapter.DataviewHolder) .bind() 这样做并创建另一个 class 正如我看到的那样是在另一个线程中完成的 (
//我也知道我正在使用将在年底到期的 android 扩展。但现在它可以工作,一旦我准备好代码并且 运行 我将开始转向更新版本的 kotlin。
顾名思义,RecyclerView 将在视图离开屏幕时回收视图。这意味着当一个项目的视图进入视图时,它会被重新创建并调用 onBindViewHolder()
来填充详细信息。
您的适配器内的 onClickListener
更改了单元格视图的其中一个子视图的背景。但是,如果该单元格离开屏幕并返回,它将被重新绘制。
为了解决这个问题,您的 onClickListener 应该更改数据项上的 属性,并且您的 onBindViewHolder
应该检查 属性 以确定要显示的背景颜色子视图:
enum class DataState {
Unselected,
Success,
Failure
}
data class DataItem(var state: DataState = DataState.Unselected)
class MyAdapter : RecyclerView.Adapter<MyViewHolder>() {
var dataItems: List<DataItem> = emptyList()
fun updateData(data: List<DataItem>) {
dataItems = data
notifyDataSetChanged()
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val dataItem = dataItems[position]
holder.txttvdone.apply {
setBackgroundResource(when (dataItem.state) {
DataState.Unselected -> android.R.color.transparent
DataState.Success -> R.color.green
DataState.Failure -> R.color.orange
})
text = when (dataItem.state) {
DataState.Unselected -> ""
DataState.Success -> "✓"
DataState.Failure -> "x"
}
}
holder.apply {
txtbutton1.setOnClickListener {
Log.e("Clicked", "Successful delivery")
dataItem.state = DataState.Success
notifyDataSetChanged()
}
txtbutton2.setOnClickListener {
Log.e("Clicked", "Exception on delivery")
dataItem.state = DataState.Failure
notifyDataSetChanged()
}
}
}
}