5

I'm using DataBinding with the following layout. I'm calling the setViewModel() method on the binding object. If I immediately call binding.getViewModel(), it returns null. See code below:

Layout:

<layout>
<data>
    <variable
        name="viewModel"
        type="reyes.r.christopher.spenderbender.viewmodel.TransactionViewModel"/>
</data>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TableLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/viewExpenseListTable"
        android:shrinkColumns="*"
        android:stretchColumns="*"
        >
    </TableLayout>
</ScrollView>
</layout>

Activity:

public class ViewExpenseListActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityViewExpenseListBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_view_expense_list);

        LocalDatabaseHandler dbh = new LocalDatabaseHandler(this);
        TransactionViewModel viewModel = new TransactionViewModel(dbh);

        binding.setViewModel(viewModel);
        if ( BuildConfig.DEBUG ) {
            if (viewModel == null) {
                throw new AssertionError("Somehow viewModel is null...");
            }
            if(binding.getViewModel() == null) {
                // This Assertion is always thrown
                throw new AssertionError("viewModel is not null, but wasn't set in the binding");
            }
        }
        // Throws NullPointerException
        binding.getViewModel().loadAllExpenses();
    }
    ...
}

You may notice that I'm not using the variable anywhere in the layout. I'm trying to programmatically replace the rows in the table with values from the database whenever new rows are added to the database. That's why I need to get the viewModel from the binding.

PS: I found this similar question: Android Databinding Adapter Null Pointer Exception. This person was getting a Null Pointer Exception when they called the set method, not the get method. I can call the set method just fine, but the get returns a null object.

1 Answer 1

7

Turns out, if the variable isn't referenced in the layout, then the generated setters and getters aren't implemented.

I decided to post this in case anyone else had a similar question in the future, but I discovered this upon investigating the generated file. Here's what the getViewModel() and setViewModel() methods look like in the generated ActivityViewExpenseListBinding class:

public void setViewModel(reyes.r.christopher.spenderbender.viewmodel.TransactionViewModel viewModel) {
    // not used, ignore
}
public reyes.r.christopher.spenderbender.viewmodel.TransactionViewModel getViewModel() {
    return null;
}

I need to either reference the viewModel variable from within the layout, or use a different pattern for observing changes.

Sign up to request clarification or add additional context in comments.

1 Comment

Or, create a subclass of your binding that tracks the TransactionViewModel.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.