Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Can I avoid `!!` everywhere when I'm using Android View Binding with Kotlin?

I’m playing around with Kotlin on Android and one thing makes me confused.

When I converted few Fragments from Java to Kotlin I got this:

class XFragment : Fragment() {
    
    private var binding: FragmentXBinding? = null

    override fun onCreateView(inflater: LayoutInflater,
                          container: ViewGroup?, savedInstanceState: Bundle?): View? {
        binding = FragmentUhfReadBinding.inflate(inflater, container, false)
        return binding!!.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding!!.slPower.addOnChangeListener(this)
        binding!!.btnClearTagList.setOnClickListener(this)
    }

    // ...

    private fun updateUi(){
        binding!!.someTextView.text = getSomeTextViewText()
        binding!!.someSlider.value = getSomeSliderValue()
    }

}

I can’t make binding non-nullable, because it has to be initialized after XFragment class constructor, in onCreateView() or later.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

So with this approach it has to be nullable and I have to put !! everywhere.

Is there some way to avoid these !!?

>Solution :

The official documentation suggests this strategy:

private var _binding: FragmentXBinding? = null

// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!

Ultimately, it becomes just like requireActivity() and requireContext(). You just need to remember not to use it in a callback that might get called outside the view lifecycle.

Note, you can create your view using the super-constructor layout parameter and then bind to the pre-existing view in onViewCreated. Then you might not even need to have it in a property. I rarely need to do anything with it outside onViewCreated() and functions directly called by it:

class XFragment : Fragment(R.layout.fragment_x) {

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val binding = FragmentXBinding.bind(view)
        binding.slPower.addOnChangeListener(this)
        binding.btnClearTagList.setOnClickListener(this)
    }

}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading