如何使用Android Kotlin查看所有复选框的值?我的指针异常

发布于 2025-02-04 17:45:27 字数 10638 浏览 3 评论 0原文

有关问题的逻辑,您可以参考以下问题: - 逻辑

问题 我到了这一点。请帮助我解决这个问题。

这是活动代码: -

class CheckboxesActivity : AppCompatActivity() {

    lateinit var recyclerView: RecyclerView
    lateinit var adapter: CheckboxAdapter


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_trail)
        recyclerView =findViewById(R.id.trail_rv)

        val list = listOf(
            RowModel(RowType.TopHeader, "", "", false),
            RowModel(RowType.Course, "", "Science", false),
            RowModel(RowType.SubjectRow, "Physics", "Science", false),
            RowModel(RowType.SubjectRow, "Math", "Science", false),
            RowModel(RowType.SubjectRow, "Chemistry", "Science", false),
            RowModel(RowType.Course, "", "Arts", false),
            RowModel(RowType.SubjectRow, "Economics", "Arts", false),
            RowModel(RowType.SubjectRow, "History", "Arts", false),
            RowModel(RowType.SubjectRow, "Political Science", "Arts", false),
            RowModel(RowType.Course, "", "Commerce", false),
            RowModel(RowType.SubjectRow, "Accountancy", "Commerce", false),
            RowModel(RowType.SubjectRow, "Business Studies", "Commerce", false),
            RowModel(RowType.SubjectRow, "Physical Education", "Commerce", false)
        )

        adapter = CheckboxAdapter(this, list)
        adapter.setList(list)
        recyclerView.adapter = adapter
        recyclerView.layoutManager = LinearLayoutManager(this)

        findViewById<Button>(R.id.showTextBtn).setOnClickListener {
            selectedCheckboxes!!.clear()
            val checkboxesValue: String = selectedCheckboxes!!.joinToString(separator = ";")
            findViewById<TextView>(R.id.ShowTextView).text = checkboxesValue
        }

    }
}

这是我的适配器代码: -

class CheckboxAdapter(
    private val context: Context,
    var productList: List<RowModel>,
) : RecyclerView.Adapter<CheckboxAdapter.TableViewHolder>() {


    override fun onBindViewHolder(holder: TableViewHolder, position: Int) {

    val item = productList[position]

        holder.checkBox.setOnCheckedChangeListener(null)
        holder.checkBox.isChecked = item.isChecked

        val params: ViewGroup.MarginLayoutParams =
            holder.checkBox.layoutParams as ViewGroup.MarginLayoutParams

        when (item.rowType) {
            RowType.TopHeader -> {
                holder.checkBox.text = "All Courses"

                holder.checkBox.visibility = View.VISIBLE

                holder.checkBox.typeface = Typeface.DEFAULT_BOLD

                params.setMargins(0, 0, 0, 0)
                holder.checkBox.layoutParams = params

            }
            RowType.Course -> {

                holder.checkBox.visibility = View.VISIBLE
                holder.checkBox.text = item.category


                holder.checkBox.typeface = Typeface.DEFAULT_BOLD
                params.setMargins(0, 0, 0, 0)
                holder.checkBox.layoutParams = params

            }
            RowType.SubjectRow -> {

                holder.checkBox.visibility = View.VISIBLE
                holder.checkBox.text = item.subjectName
                holder.checkBox.typeface = Typeface.DEFAULT
                params.setMargins(convertDpToPixel(20f, context).toInt(), 0, 0, 0)
                holder.checkBox.layoutParams = params
            }
        }


        holder.checkBox.setOnCheckedChangeListener { _, isChecked ->
            if (item.isChecked != isChecked) {
                item.isChecked = isChecked

                when (item.rowType) {
                    RowType.TopHeader -> {
                        val indexList = mutableListOf<Int>()
                        productList.filter { it.rowType != RowType.TopHeader }.forEach {
                            it.isChecked = isChecked
                            indexList.add(productList.indexOf(it))
                        }
                        indexList.forEach {
                            notifyItemChanged(it)
                        }
                    }
                    RowType.Course -> {
                        val indexList = mutableListOf<Int>()
                        productList.filter { it.rowType == RowType.SubjectRow && it.category == item.category }
                            .forEach {
                                it.isChecked = isChecked
                                indexList.add(productList.indexOf(it))
                            }
                        indexList.forEach {
                            notifyItemChanged(it)
                        }
                        isAllItemsSameStatus() //for header

                    }
                    RowType.SubjectRow -> {
                        isAllItemsSameStatus(item.category) //set prep area accordingly
                        isAllItemsSameStatus() //set top header
                    }
                }
            }
        }

        when (item.rowType) {
            RowType.SubjectRow -> {
                if (holder.checkBox.isChecked)
                    selectedCheckboxes?.add(holder.checkBox.text.toString())
                if (!holder.checkBox.isChecked) {
                    Toast.makeText(context, holder.checkBox.text, Toast.LENGTH_SHORT).show()
                    selectedCheckboxes?.remove(holder.checkBox.text.toString())
                }
            }
        }
    }


    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TableViewHolder {
        return TableViewHolder(
            LayoutInflater.from(context).inflate(
                R.layout.rv_trail,
                parent,
                false
            )
        )
    }

    class TableViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

        val checkBox: CheckBox = itemView.findViewById(R.id.trailCheckbox)

    }

    override fun getItemCount() = productList.size


    fun setList(profiles: List<RowModel>) {
        productList = profiles
        notifyDataSetChanged()
    }

    private fun isAllItemsSameStatus(cat: String? = null) {

        val row: RowModel
        var isChecked: Boolean = true
        var position: Int = 0

        if (cat != null) {
            val catRow = productList.find { it.rowType == RowType.Course && it.category == cat }
            catRow?.let {
                val subList =
                    productList.filter { it.category == it.category && it.rowType == RowType.SubjectRow }
                isChecked = subList.filter { it.isChecked }.size == subList.size
                position = productList.indexOf(catRow)
            }
            if (catRow == null)
                return
            else
                row = catRow
        } else {
            row = productList[0]
            isChecked =
                productList.filter { it.rowType != RowType.TopHeader && it.isChecked }.size == productList.size - 1
            position = 0
        }

        updateHeader(row, isChecked, position)
    }


    private fun updateHeader(item: RowModel, isChecked: Boolean, position: Int) {
        if (item.isChecked != isChecked) // no need to update if no change
        {
            item.isChecked = isChecked
            notifyItemChanged(position)

        }
    }

    private fun convertDpToPixel(dp: Float, context: Context): Float {
        return dp * (context.resources
            .displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT)
    }

    companion object {
        var selectedCheckboxes: MutableList<String>? = null
    }

}

这是我的模型代码: -

data class RowModel (
    val rowType: RowType,
    val subjectName: String,
    val category: String,
    var isChecked: Boolean = true)

enum class RowType(val id : Int) {

    TopHeader(1),
    Course(2),
    SubjectRow(3);

}

这是Activity_trail布局代码: -

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".CheckboxesActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/trail_rv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <Button
        android:id="@+id/showTextBtn"
        style="@style/ButtonTransparent"
        android:text="@string/save"/>

    <TextView
        android:id="@+id/ShowTextView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>


</LinearLayout>

问题的逻辑是: -

我正在尝试进行活动,如果: - 1)所有课程选择复选框,然后应检查所有其他复选框,反之亦然。

2)检查所有科学按钮,然后选择所有其他主题按钮,反之亦然。所有其他主题也一样。

3)如果未检查任何课程按钮,则也不应检查所有课程按钮。所有主题也一样。

单击ShowTextBtn(按钮)之后。该应用程序正在崩溃。这是崩溃报告: -

java.lang.NullPointerException
        at com.trail.CheckboxesActivity.onCreate$lambda-0(CheckboxesActivity.kt:45)
        at com.trail.CheckboxesActivity.$r8$lambda$Q7Wv2MEY_mNrpZmgjbfsuGABR0o(Unknown Source:0)
        at com.trail.CheckboxesActivity$$ExternalSyntheticLambda0.onClick(Unknown Source:2)
        at android.view.View.performClick(View.java:8160)
        at android.widget.TextView.performClick(TextView.java:16222)
        at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1194)
        at android.view.View.performClickInternal(View.java:8137)
        at android.view.View.access$3700(View.java:888)
        at android.view.View$PerformClick.run(View.java:30236)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:246)
        at android.app.ActivityThread.main(ActivityThread.java:8653)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)

在这里,我正在尝试获取所有选定的复选框的文本。 在文本视图中显示该文本。 其他所有内容都可以正常工作,但是问题仅在获取所选复选框的值文本应用程序崩溃时。 如果可能的话,您能告诉我如何使用字符串阵列而不是输入所有这些列表?

for logic of the question you can refer to this question:-
question Logic

After lots of efforts I have came to this point. Please help me solving this problem.

Here is activity code:-

class CheckboxesActivity : AppCompatActivity() {

    lateinit var recyclerView: RecyclerView
    lateinit var adapter: CheckboxAdapter


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_trail)
        recyclerView =findViewById(R.id.trail_rv)

        val list = listOf(
            RowModel(RowType.TopHeader, "", "", false),
            RowModel(RowType.Course, "", "Science", false),
            RowModel(RowType.SubjectRow, "Physics", "Science", false),
            RowModel(RowType.SubjectRow, "Math", "Science", false),
            RowModel(RowType.SubjectRow, "Chemistry", "Science", false),
            RowModel(RowType.Course, "", "Arts", false),
            RowModel(RowType.SubjectRow, "Economics", "Arts", false),
            RowModel(RowType.SubjectRow, "History", "Arts", false),
            RowModel(RowType.SubjectRow, "Political Science", "Arts", false),
            RowModel(RowType.Course, "", "Commerce", false),
            RowModel(RowType.SubjectRow, "Accountancy", "Commerce", false),
            RowModel(RowType.SubjectRow, "Business Studies", "Commerce", false),
            RowModel(RowType.SubjectRow, "Physical Education", "Commerce", false)
        )

        adapter = CheckboxAdapter(this, list)
        adapter.setList(list)
        recyclerView.adapter = adapter
        recyclerView.layoutManager = LinearLayoutManager(this)

        findViewById<Button>(R.id.showTextBtn).setOnClickListener {
            selectedCheckboxes!!.clear()
            val checkboxesValue: String = selectedCheckboxes!!.joinToString(separator = ";")
            findViewById<TextView>(R.id.ShowTextView).text = checkboxesValue
        }

    }
}

here is my adapter code:-

class CheckboxAdapter(
    private val context: Context,
    var productList: List<RowModel>,
) : RecyclerView.Adapter<CheckboxAdapter.TableViewHolder>() {


    override fun onBindViewHolder(holder: TableViewHolder, position: Int) {

    val item = productList[position]

        holder.checkBox.setOnCheckedChangeListener(null)
        holder.checkBox.isChecked = item.isChecked

        val params: ViewGroup.MarginLayoutParams =
            holder.checkBox.layoutParams as ViewGroup.MarginLayoutParams

        when (item.rowType) {
            RowType.TopHeader -> {
                holder.checkBox.text = "All Courses"

                holder.checkBox.visibility = View.VISIBLE

                holder.checkBox.typeface = Typeface.DEFAULT_BOLD

                params.setMargins(0, 0, 0, 0)
                holder.checkBox.layoutParams = params

            }
            RowType.Course -> {

                holder.checkBox.visibility = View.VISIBLE
                holder.checkBox.text = item.category


                holder.checkBox.typeface = Typeface.DEFAULT_BOLD
                params.setMargins(0, 0, 0, 0)
                holder.checkBox.layoutParams = params

            }
            RowType.SubjectRow -> {

                holder.checkBox.visibility = View.VISIBLE
                holder.checkBox.text = item.subjectName
                holder.checkBox.typeface = Typeface.DEFAULT
                params.setMargins(convertDpToPixel(20f, context).toInt(), 0, 0, 0)
                holder.checkBox.layoutParams = params
            }
        }


        holder.checkBox.setOnCheckedChangeListener { _, isChecked ->
            if (item.isChecked != isChecked) {
                item.isChecked = isChecked

                when (item.rowType) {
                    RowType.TopHeader -> {
                        val indexList = mutableListOf<Int>()
                        productList.filter { it.rowType != RowType.TopHeader }.forEach {
                            it.isChecked = isChecked
                            indexList.add(productList.indexOf(it))
                        }
                        indexList.forEach {
                            notifyItemChanged(it)
                        }
                    }
                    RowType.Course -> {
                        val indexList = mutableListOf<Int>()
                        productList.filter { it.rowType == RowType.SubjectRow && it.category == item.category }
                            .forEach {
                                it.isChecked = isChecked
                                indexList.add(productList.indexOf(it))
                            }
                        indexList.forEach {
                            notifyItemChanged(it)
                        }
                        isAllItemsSameStatus() //for header

                    }
                    RowType.SubjectRow -> {
                        isAllItemsSameStatus(item.category) //set prep area accordingly
                        isAllItemsSameStatus() //set top header
                    }
                }
            }
        }

        when (item.rowType) {
            RowType.SubjectRow -> {
                if (holder.checkBox.isChecked)
                    selectedCheckboxes?.add(holder.checkBox.text.toString())
                if (!holder.checkBox.isChecked) {
                    Toast.makeText(context, holder.checkBox.text, Toast.LENGTH_SHORT).show()
                    selectedCheckboxes?.remove(holder.checkBox.text.toString())
                }
            }
        }
    }


    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TableViewHolder {
        return TableViewHolder(
            LayoutInflater.from(context).inflate(
                R.layout.rv_trail,
                parent,
                false
            )
        )
    }

    class TableViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

        val checkBox: CheckBox = itemView.findViewById(R.id.trailCheckbox)

    }

    override fun getItemCount() = productList.size


    fun setList(profiles: List<RowModel>) {
        productList = profiles
        notifyDataSetChanged()
    }

    private fun isAllItemsSameStatus(cat: String? = null) {

        val row: RowModel
        var isChecked: Boolean = true
        var position: Int = 0

        if (cat != null) {
            val catRow = productList.find { it.rowType == RowType.Course && it.category == cat }
            catRow?.let {
                val subList =
                    productList.filter { it.category == it.category && it.rowType == RowType.SubjectRow }
                isChecked = subList.filter { it.isChecked }.size == subList.size
                position = productList.indexOf(catRow)
            }
            if (catRow == null)
                return
            else
                row = catRow
        } else {
            row = productList[0]
            isChecked =
                productList.filter { it.rowType != RowType.TopHeader && it.isChecked }.size == productList.size - 1
            position = 0
        }

        updateHeader(row, isChecked, position)
    }


    private fun updateHeader(item: RowModel, isChecked: Boolean, position: Int) {
        if (item.isChecked != isChecked) // no need to update if no change
        {
            item.isChecked = isChecked
            notifyItemChanged(position)

        }
    }

    private fun convertDpToPixel(dp: Float, context: Context): Float {
        return dp * (context.resources
            .displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT)
    }

    companion object {
        var selectedCheckboxes: MutableList<String>? = null
    }

}

here is my model code:-

data class RowModel (
    val rowType: RowType,
    val subjectName: String,
    val category: String,
    var isChecked: Boolean = true)

enum class RowType(val id : Int) {

    TopHeader(1),
    Course(2),
    SubjectRow(3);

}

here is activity_trail layout code:-

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".CheckboxesActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/trail_rv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <Button
        android:id="@+id/showTextBtn"
        style="@style/ButtonTransparent"
        android:text="@string/save"/>

    <TextView
        android:id="@+id/ShowTextView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>


</LinearLayout>

The logic of the question is :-

I am trying to make to activity that if:- 1)all courses checkbox is selected then all other checkboxes should be checked and vice versa.

2)all science button is checked then all other subjects buttons should be selected and vice versa. Same for all other subjects as well.

3)if any course button is not checked then all courses button should also not be checked. Same for all subjects as well.

After clicking showTextBtn (Button). The app is crashing. Here is the crash report:-

java.lang.NullPointerException
        at com.trail.CheckboxesActivity.onCreate$lambda-0(CheckboxesActivity.kt:45)
        at com.trail.CheckboxesActivity.$r8$lambda$Q7Wv2MEY_mNrpZmgjbfsuGABR0o(Unknown Source:0)
        at com.trail.CheckboxesActivity$ExternalSyntheticLambda0.onClick(Unknown Source:2)
        at android.view.View.performClick(View.java:8160)
        at android.widget.TextView.performClick(TextView.java:16222)
        at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1194)
        at android.view.View.performClickInternal(View.java:8137)
        at android.view.View.access$3700(View.java:888)
        at android.view.View$PerformClick.run(View.java:30236)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:246)
        at android.app.ActivityThread.main(ActivityThread.java:8653)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)

Here I am trying to get the text of all the selected checkboxes.
Show that text in the textView.
Every other thing is working fine but the problem is only while getting the values of selected checkboxes text app is crashing.
If possible can you tell me if how can I use string-array instead of typing all these list?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

污味仙女 2025-02-11 17:45:27

而不是使用: -

var selectedCheckboxes: MutableList<String>? = null

使用: -

var selectedCheckboxes: ArrayList<String> = ArrayList()

Instead of using :-

var selectedCheckboxes: MutableList<String>? = null

use:-

var selectedCheckboxes: ArrayList<String> = ArrayList()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文