【问题标题】:Android Studio Kotlin, notifyItemChanged not calling OnBindViewHolderAndroid Studio Kotlin,notifyItemChanged 不调用 OnBindViewHolder
【发布时间】:2021-11-17 22:40:11
【问题描述】:

我正在尝试使用 kotlin 在 Android Studio 中制作基于生命网格的游戏。本质上,网格将根据一组规则每秒钟更新一次。但是,我这辈子都无法更新网格。

由于某种原因,notifyItemChanged() 没有调用 onBindViewHolder 来正确更新网格。在某些情况下,我能够找到解决方法,即专门调用 onBindViewHolder 并通过当前的 cellViewHolder 及其位置,但这不会让我得到我正在寻找的结果。具体来说,在我声明 testUpdate() 的函数中,我需要能够更改网格所基于的数据数组,然后从该函数通知网格发生了更改并且应该更新。但是,notifyItemChanged() 和 notifyDatasetChanged() 都不会调用 onBindViewHolder()。我很茫然,任何帮助将不胜感激!

我对 Kotlin 很陌生,所以如果这段代码很糟糕,我深表歉意。

这是我的代码:

package com.example.project2

import android.graphics.Color
import android.os.Bundle
import android.text.Layout
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.ImageButton
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import android.os.Handler;

class BoardFragment : Fragment() {
    private lateinit var recyclerView: RecyclerView
    var gridArray = IntArray(400)
    val handler = Handler()
    var isRunning: Boolean = false
    val colorRed = Color.RED
    val colorBlue = Color.BLUE

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.board_fragment, container, false)

        val startButton = view.findViewById(R.id.start_button) as Button

        val recyclerView = view.findViewById(R.id.recycler_view) as RecyclerView
        recyclerView.layoutManager = GridLayoutManager(activity, 20)
        recyclerView.adapter = GridAdapter()

        startButton.setOnClickListener {
            isRunning = !isRunning
            if (isRunning) {
                testUpdate()
            }
        }

        return view
    }

    fun testUpdate() {
        handler.postDelayed({
            if (gridArray[3] == 0) {
                gridArray[3] = 1
            } else {
                gridArray[3] = 0
            }

            if (isRunning) {
                testUpdate()
            }
            GridAdapter().notifyItemChanged(3)
        }, 1000)
    }

    override fun onStart() {
        super.onStart()
    }

    private inner class CellViewHolder(cellView: View): RecyclerView.ViewHolder(cellView) {
        val button: ImageButton

        init {
            button = cellView.findViewById(R.id.cell_button)

            button.setColorFilter(null)
            button.setOnClickListener {
                if (gridArray[position] == 0) {
                    gridArray[position] = 1
                } else {
                    gridArray[position] = 0
                }
                GridAdapter().notifyItemChanged(position)
                GridAdapter().onBindViewHolder(this, position)
            }
        }

        fun display(position: Int) {

        }
    }

    private inner class GridAdapter: RecyclerView.Adapter<CellViewHolder>() {

        final val NUM_CELLS: Int = 400

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CellViewHolder {
            val inflater: LayoutInflater = LayoutInflater.from(parent.context)
            val cellView: View = inflater.inflate(R.layout.board_cell, parent, false)
            return CellViewHolder(cellView)
        }

        override fun onBindViewHolder(holder: CellViewHolder, position: Int) {
            holder.display(position)
            if (gridArray[position] == 0) {
                holder.button.setColorFilter(null)
            } else {
                holder.button.setColorFilter(Color.RED)
            }

        }

        override fun getItemCount(): Int {
            return NUM_CELLS
        }
    }

}

【问题讨论】:

    标签: android kotlin grid adapter notifyitemchanged


    【解决方案1】:

    我不知道你想要达到什么目的,但有一些提示

    1. notifyItemChange() 应该从 Adapter 类中调用。
    2. 您正在创建 GridAdapter GridAdapter().notifyItemChanged(position) 的新实例

    改变

    GridAdapter().notifyItemChanged(position)
    

    recyclerView.adapter.notifyItemChanged(position)
    

    像这样修改你的类

    package com.example.project2
    
    import android.graphics.Color
    import android.os.Bundle
    import android.text.Layout
    import android.view.LayoutInflater
    import android.view.View
    import android.view.ViewGroup
    import android.widget.Button
    import android.widget.ImageButton
    import android.widget.TextView
    import androidx.fragment.app.Fragment
    import androidx.recyclerview.widget.GridLayoutManager
    import androidx.recyclerview.widget.RecyclerView
    import android.os.Handler;
    
    class BoardFragment : Fragment() {
        private lateinit var recyclerView: RecyclerView
        var gridArray = IntArray(400)
        val handler = Handler()
        var isRunning: Boolean = false
        val colorRed = Color.RED
        val colorBlue = Color.BLUE
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
        }
    
        override fun onCreateView(
            inflater: LayoutInflater,
            container: ViewGroup?,
            savedInstanceState: Bundle?
        ): View? {
            val view = inflater.inflate(R.layout.board_fragment, container, false)
    
            val startButton = view.findViewById(R.id.start_button) as Button
    
            val recyclerView = view.findViewById(R.id.recycler_view) as RecyclerView
    
            recyclerView.layoutManager = GridLayoutManager(activity, 20)
            
            recyclerView.adapter = GridAdapter()
    
            startButton.setOnClickListener {
                isRunning = !isRunning
                if (isRunning) {
                    testUpdate()
                }
            }
    
            return view
        }
    
        fun testUpdate() {
            handler.postDelayed({
                if (gridArray[3] == 0) {
                    gridArray[3] = 1
                } else {
                    gridArray[3] = 0
                }
    
                if (isRunning) {
                    testUpdate()
                }
                recyclerView.adapter.notifyItemChanged(3)
            }, 1000)
        }
    
        override fun onStart() {
            super.onStart()
        }
    
        private inner class CellViewHolder(cellView: View): RecyclerView.ViewHolder(cellView) {
            val button: ImageButton
    
            init {
                button = cellView.findViewById(R.id.cell_button)
    
                button.setColorFilter(null)
                button.setOnClickListener {
                    if (gridArray[position] == 0) {
                        gridArray[position] = 1
                    } else {
                        gridArray[position] = 0
                    }
    
                }
            }
    
            fun display(position: Int) {
    
            }
        }
    
        private inner class GridAdapter: RecyclerView.Adapter<CellViewHolder>() {
    
            final val NUM_CELLS: Int = 400
    
            override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CellViewHolder {
                val inflater: LayoutInflater = LayoutInflater.from(parent.context)
                val cellView: View = inflater.inflate(R.layout.board_cell, parent, false)
                return CellViewHolder(cellView)
            }
    
            override fun onBindViewHolder(holder: CellViewHolder, position: Int) {
                
                if (gridArray[position] == 0) {
                    holder.button.setColorFilter(null)
                } else {
                    holder.button.setColorFilter(Color.RED)
                }
    
          holder.display(position)
    recyclerView.adapter.notifyItemChanged(3)
            }
    
            override fun getItemCount(): Int {
                return NUM_CELLS
            }
        }
    
    }
    

    【讨论】:

    • 在我的代码中的任何位置使用 recyclerView.adapter.notifyItemChanged(3) 会导致应用程序不断崩溃。我想要完成的是每次处理程序延迟一秒钟,更新网格并根据单元格在数组中的位置显示某种颜色。感谢您的帮助
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-30
    • 1970-01-01
    相关资源
    最近更新 更多