使用Room自动保留两种方式的数据绑定更改?

Ed *_*ave 6 android-databinding android-room android-livedata android-viewmodel

双向数据绑定允许您使用来自对象的数据自动填充UI组件,然后在用户编辑这些UI组件时自动更新对象。

当用户编辑UI组件时,是否有一种方法不仅可以自动更新内存中的对象,还可以自动更新/将对象保留在Room数据库中?

我可以手动收听每个UI字段的修改,然后将对象手动保存到Room数据库。但是,这种手动的蛮力方法会否定我希望利用的双向数据绑定的好处。

语境

我的应用程序使用Android的Room Persistence Library将项目存储在SQLite数据库中。这是我的物品的简化版本:

@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;
    }
}
Run Code Online (Sandbox Code Playgroud)

ViewModel,LiveData和双向数据绑定的魔力使我的ItemEditorFragment可以自动使用所选项目中的数据填充UI,并在用户编辑UI组件时更新该项目:

@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;
}
Run Code Online (Sandbox Code Playgroud)

这是正在膨胀的布局的简化版本:

<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>
Run Code Online (Sandbox Code Playgroud)

Ale*_*vić 1

我所做的肮脏黑客之一是:创建一个新属性,在ViewModel(但它并不严格必须完全在那里),没有支持字段(在Java中,这可能相当于创建一个getter和一个 setter,没有字段):

    var selectedItemName: String?

        get() = selectedItem.value?.name

        set(value) {
            selectedItem.value?.let {
                    it.name = value
                    dao.update(it)
                }
        }
Run Code Online (Sandbox Code Playgroud)

这不是一个理想的解决方案,因为它需要镜像类中的所有属性,但如果您只想结束它,它就可以了。我正在等待更好的解决方案!