In my application I have BottomSheetDialogFragment and into this fragment
I have ChipGroup
.
I want dynamically checked chip of this ChipGroup
.
I write below code, when first time open this dialog, everything is okey and show checked chip.
But when close dialog and open again dialog crashed application and show null error!
My fragment codes:
class MenuFragment : BottomSheetDialogFragment() {
//Binding
private var _binding: FragmentMenuBinding? = null
private val binding get() = _binding!!
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
_binding = FragmentMenuBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
//InitView
binding.apply {
setupChip(fillChipData(), mealChipGroup)
mealChipGroup.findViewById<Chip>(3).isChecked = true
}
private fun fillChipData(): MutableList<String> {
return mutableListOf(
"Item1", "Item2", "Item3", "Item4", "Item5"
)
}
private fun setupChip(list: MutableList<String>, view: ChipGroup) {
list.forEach {
val chip = Chip(requireContext())
chip.text = it
view.addView(chip)
}
}
override fun onDestroy() {
super.onDestroy()
_binding = null
}
Error message:
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.google.android.material.chip.Chip.setChecked(boolean)' on a null object reference
at myapp.MenuFragment.onViewCreated(MenuFragment.kt:58)
at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:3128)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:552)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:261)
at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1899)
at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1823)
at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1760)
at androidx.fragment.app.FragmentManager$5.run(FragmentManager.java:547)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6121)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779)
Show me error for this line :
mealChipGroup.findViewById<Chip>(3).isChecked = true
I know this error for NullPointerException, but my question is why in first time everything is ok. But when close and open dialog show me this error?!!
How can I fix it?
CodePudding user response:
Posting as an Answer along with the comment I've added.
You are dynamically creating Chips but without setting up an id, and you are trying to access a Chip via an id 3 which doesn't exist, hence the NullPointerException
.
Use setId
on your created Chip
and use that to access the view.
Example:
// 1. Create a variable with a default value of '1' so that we can move sequentially for each Chip's id.
var chipId = 1
// 2. Set 'Id' to your programmatically created Chip.
private fun setupChip(list: MutableList<String>, view: ChipGroup) {
list.forEach {
val chip = Chip(requireContext())
chip.text = it
chip.id = counter // <<<< this
view.addView(chip)
}
}
// 3. Now you can access the "third" Chip like before
mealChipGroup.findViewById<Chip>(3).isChecked = true