如何使用Android Kotlin查看所有复选框的值?我的指针异常
有关问题的逻辑,您可以参考以下问题: - 逻辑
这是活动代码: -
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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
而不是使用: -
使用: -
Instead of using :-
use:-