Home > Net >  How to use ChipGroup in Android
How to use ChipGroup in Android

Time:12-04

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
  • Related