0

我正在尝试使用 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
        }
    }

}
4

1 回答 1

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
        }
    }

}
于 2021-11-18T02:40:43.230 回答