You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin中lateinit变量selectAllCheckBox回调时显示未初始化问题

问题:notifyAllIsChecked中selectAllCheckBox显示未初始化的问题

我需要在重写的notifyAllIsChecked方法中使用selectAllCheckBox变量,但该变量显示未初始化,尽管它已在onCreate方法中完成初始化。日志显示该变量在notifyAllIsChecked方法调用前已经完成初始化,但回调时检测结果为未初始化。

相关代码

package com.example.lslmbeta

import android.annotation.SuppressLint
import android.os.Bundle
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.WindowCompat
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.lslmbeta.databinding.ActivityMainBinding
import com.example.lslmbeta.datamanagement.dataReader
import com.example.lslmbeta.recyclerview.ItemAdapter
import com.google.android.material.appbar.MaterialToolbar
import com.google.android.material.checkbox.MaterialCheckBox
import kotlinx.coroutines.launch
import java.text.SimpleDateFormat


class MainActivity : AppCompatActivity(), OnAllIsCheckedListener {
    companion object {
        var isInSelectionMode: Boolean? = null
    }

    private val MAIN_ACTIVITY_TAG = "Main Activity"

    private lateinit var recyclerView: RecyclerView

    private lateinit var closeView: MenuItem
    private lateinit var selectView: MenuItem
    private lateinit var moreView: MenuItem

    private lateinit var itemAdapter: ItemAdapter
    private lateinit var selectAllCheckBox: MaterialCheckBox

    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        menuInflater.inflate(R.menu.top_app_bar, menu)

        // Menu Group Selection
        closeView = menu.findItem(R.id.menu_item_close)

        // Menu Group Non Selection
        selectView = menu.findItem(R.id.menu_item_select)
        moreView = menu.findItem(R.id.menu_item_more)

        enableOrDisableSelection()

        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        return when (item) {
            closeView -> {
                enableOrDisableSelection()
                true
            }

            selectView -> {
                if (::itemAdapter.isInitialized) enableOrDisableSelection()
                true
            }

            moreView -> {
                // Gestisci il clic sull'elemento "More" (menu a scomparsa)
                true
            }

            else -> super.onOptionsItemSelected(item)
        }
    }

    //TODO togliere il suppress
    @SuppressLint("SimpleDateFormat")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val binding = ActivityMainBinding.inflate(layoutInflater)
        val view = binding.root
        setContentView(view)

        val topToolBar = binding.topToolBar
        setSupportActionBar(topToolBar)

        WindowCompat.setDecorFitsSystemWindows(window, false)

        val dateString = "19/10/2023"
        val dateFormat = SimpleDateFormat("dd/MM/yyyy")
        val date = dateFormat.parse(dateString)

        recyclerView = binding.homeRecycleView
        selectAllCheckBox = binding.selectAllCheckbox

        Log.d(MAIN_ACTIVITY_TAG, "Select All Checkbox: ${::selectAllCheckBox.isInitialized}")

        selectAllCheckBox.setOnClickListener {
            if (selectAllCheckBox.isChecked) {
                itemAdapter.checkAll()
            } else {
                itemAdapter.clearCheckedItems()
            }
        }

        lifecycleScope.launch {
            val myDataset = dataReader(this@MainActivity, date)
            itemAdapter = ItemAdapter(myDataset)
            recyclerView.layoutManager = LinearLayoutManager(this@MainActivity)
            recyclerView.adapter = itemAdapter
            recyclerView.setHasFixedSize(true)

            itemAdapter.setCustomListener(MainActivity())
        }
    }

    override fun notifyAllIsChecked(isAllChecked: Boolean) {
        Log.d(MAIN_ACTIVITY_TAG, "Is Ready: ${::selectAllCheckBox.isInitialized}")

        if (::selectAllCheckBox.isInitialized) selectAllCheckBox.isChecked = isAllChecked
    }

    @SuppressLint("NotifyDataSetChanged")
    private fun enableOrDisableSelection() {
        val topToolBar = findViewById<MaterialToolbar>(R.id.topToolBar)
        val checkBox = findViewById<MaterialCheckBox>(R.id.select_all_checkbox)

        if (isInSelectionMode == null) {
            isInSelectionMode = false
            Log.w("Enable Or Disable Selection", "Is NULL")
        } else {
            isInSelectionMode = !isInSelectionMode!!
        }

        Log.d("Enable Or Disable Selection", isInSelectionMode.toString())

        // Group Selection
        closeView.isVisible = isInSelectionMode!!

        checkBox.isVisible = isInSelectionMode!!

        // Group Non Selection
        selectView.isVisible = !isInSelectionMode!!
        moreView.isVisible = !isInSelectionMode!!

        topToolBar.title = if (isInSelectionMode!!) "" else getString(R.string.app_name)

        if (isInSelectionMode!!) {
            itemAdapter.clearCheckedItems()
        } else {
            recyclerView.adapter?.notifyDataSetChanged()
        }
    }
}

日志信息

2023-10-29 11:56:16.938 24963-24963 Main Activity           com.example.lslmbeta                 D  Select All Checkbox: true
2023-10-29 12:09:12.864 24963-24963 Main Activity           com.example.lslmbeta                 D  Is Ready: false

问题原因

问题出在onCreate方法的这一行:

itemAdapter.setCustomListener(MainActivity())

你手动新建了一个MainActivity实例传给Adapter,而不是使用当前正在运行的Activity实例。这个手动创建的实例不会走系统的Activity生命周期流程,自然不会执行onCreate方法初始化selectAllCheckBox。当Adapter触发回调时,实际调用的是这个空实例的notifyAllIsChecked方法,因此会显示变量未初始化。

修复方案

  1. 将监听器设置改为传入当前Activity的引用:
// 替换原来的MainActivity(),用当前实例this
itemAdapter.setCustomListener(this)
  1. 优化enableOrDisableSelection方法,直接使用已初始化的selectAllCheckBox变量,避免重复调用findViewById:
@SuppressLint("NotifyDataSetChanged")
private fun enableOrDisableSelection() {
    val topToolBar = findViewById<MaterialToolbar>(R.id.topToolBar)

    if (isInSelectionMode == null) {
        isInSelectionMode = false
        Log.w("Enable Or Disable Selection", "Is NULL")
    } else {
        isInSelectionMode = !isInSelectionMode!!
    }

    Log.d("Enable Or Disable Selection", isInSelectionMode.toString())

    // Group Selection
    closeView.isVisible = isInSelectionMode!!
    // 直接使用已初始化的selectAllCheckBox
    selectAllCheckBox.isVisible = isInSelectionMode!!

    // Group Non Selection
    selectView.isVisible = !isInSelectionMode!!
    moreView.isVisible = !isInSelectionMode!!

    topToolBar.title = if (isInSelectionMode!!) "" else getString(R.string.app_name)

    if (isInSelectionMode!!) {
        itemAdapter.clearCheckedItems()
    } else {
        recyclerView.adapter?.notifyDataSetChanged()
    }
}

内容的提问来源于stack exchange,提问作者MagoLione

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 14:57:31