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方法,因此会显示变量未初始化。
修复方案
- 将监听器设置改为传入当前Activity的引用:
// 替换原来的MainActivity(),用当前实例this itemAdapter.setCustomListener(this)
- 优化
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
相关产品推荐
相关产品推荐

