Search code examples
androidandroid-layoutandroid-fragmentsandroid-databinding

Data-binding on BottomSheetDialog Layout (Crash)


I am having trouble getting data-binding to work properly on a BottomSheetDialog layout. Here are the details:

Definition and setting of var:

private lateinit var myDrawerBinding: MyDrawerBinding

myDrawerBinding = MyDrawerBinding.bind(myDrawerContent) // crashes on this line

and later it's set and shown this way (although it never gets to this point)

myDrawerBinding.viewModel = theViewModel

val bottomSheet = BottomSheetDialog(context)
bottomSheet.setContentView(myDrawerBinding.myDrawerContent)
bottomSheet.show()

Here is a snippet of the XML layout (my_drawer.xml):

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

<data>
    <import type="android.view.View"/>
    <variable name="viewModel" type="path.to.my.viewModel"/>
</data>

<RelativeLayout
        android:id="@+id/myDrawerContent"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="10dp">

    <View
            android:layout_width="50dp"
            android:layout_height="3dp"
            android:visibility="@{viewModel.shouldShowView() ? View.VISIBLE : View.GONE}"/>
....

The crash occurs when it calls the .bind() method above, and the error is:

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.view.View.getTag()' on a null object reference

This same exact functionality works on a separate DrawerLayout that I am showing in the same Fragment, but for some reason the BottomSheetDialog layout is giving problems.


Solution

  • Finally found a fix for this. I had to treat this view a little differently from my DrawerLayout, although I have a feeling this approach may work for that view as well.

    Here is the binding setup:

    val myDrawerView = layoutInflater.inflate(R.layout.my_drawer, null)
    val binding = MyDrawerBinding.inflate(layoutInflater, myDrawerView as ViewGroup, false)
    binding.viewModel = theViewModel
    

    And then to show the view:

    val bottomSheetDialog = BottomSheetDialog(context)
    bottomSheetDialog.setContentView(binding.myDrawerContent)
    bottomSheetDialog.show()
    

    Works like a charm now!