【问题标题】: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
    相关资源
    最近更新 更多