#StackBounty: #android-room #android-databinding #android-livedata #android-viewmodel Automatically persist changes from two way data b…

Bounty: 100

Question

Two-Way DataBinding allows you to automatically populate UI components with data from an Object and then automatically update the Object as the user edits those UI components.

As the user edits UI components, is there a way to not only automatically update the Object in memory, but automatically update/persist the Object in a Room database?

I could manually listen to every UI field modification and manually save the Object to the Room Database. However, such a manual, brute force approach would negate the benefits of Two-Way DataBindings that I’m hoping to utilize.

Context

My application stores Items in an SQLite database using Android’s Room Persistence Library. This is a simplified version of my Item:

@Entity
public class Item {

    @PrimaryKey(autoGenerate = true)
    private long id;

    private String name;

    public long getId() {
        return this.id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

The magic of ViewModel, LiveData, and Two-Way DataBindings allows my ItemEditorFragment to automatically populate the UI with data from the selected Item and to update that Item when the user edits the UI components:

@Override
public void onAttach(Context context) {
    super.onAttach(context);

    if (context instanceof ItemViewModelProvider) {
        final ItemViewModelProvider itemViewModelProvider = (ItemViewModelProvider) context;
        mViewModel = itemViewModelProvider.getItemViewModel();
    } else {
        throw new RuntimeException(context.toString()
                + " must implement ItemViewModelProvider");
    }
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    final FragmentItemEditorBinding binding = DataBindingUtil.inflate(inflater, R.layout.fragment_item_editor, container, false);
    binding.setViewModel(mViewModel);
    binding.setLifecycleOwner(this);

    final View view = binding.getRoot();
    return view;
}

This is a simplified version of the layout being inflated:

<layout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <data>
        <variable
            name="viewModel"
            type="com.lafave.ItemViewModel" />
    </data>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <EditText
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@={viewModel.selectedItem.name}"
            android:layout_gravity="center_horizontal"/>

    </LinearLayout>
</layout>


Get this bounty!!!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.