【问题标题】:ObservableField value inside ViewModel does not update UI with data bindingViewModel 中的 ObservableField 值不会使用数据绑定更新 UI
【发布时间】:2018-07-02 11:40:31
【问题描述】:

ObservableField<Marker> 内的值 ViewModel 类值在布局中使用 EditText 更改,但值不会传播到 TextView tv_summary

这是布局

<?xml version="1.0" encoding="utf-8"?>

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>
        <import type="com.example.tutorial5livedata_mvvm_room_recyclerview.util.BindingUtils"/>
        <variable
            name="viewModel"
            type="com.example.tutorial5livedata_mvvm_room_recyclerview.viewmodel.AddMarkerViewModel"/>

    </data>

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">


        <TextView
            android:id="@+id/tv_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="Title"
            android:textColor="#FC7100"
            android:textSize="18sp"
            android:textStyle="bold"
            app:layout_constraintStart_toStartOf="@+id/guideline_left"
            app:layout_constraintTop_toTopOf="parent" />

        <EditText
            android:id="@+id/et_title"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginEnd="8dp"
            android:layout_marginTop="8dp"
            android:ems="10"
            android:hint="Title"
            android:inputType="textPersonName"
            android:text="@={viewModel.markerObservableField.title}"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="@+id/guideline_left"
            app:layout_constraintTop_toBottomOf="@+id/tv_title" />


        <TextView
            android:id="@+id/tv_latitude"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="Latitude"
            android:textColor="#FC7100"
            android:textSize="18sp"
            android:textStyle="bold"
            app:layout_constraintStart_toStartOf="@+id/guideline_left"
            app:layout_constraintTop_toBottomOf="@+id/et_title" />

        <EditText
            android:id="@+id/et_latitude"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginEnd="8dp"
            android:layout_marginTop="8dp"
            android:ems="10"
            android:hint="Latitude"
            android:text="@={viewModel.markerObservableField.latitude}"
            android:inputType="number"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="@+id/guideline_left"
            app:layout_constraintTop_toBottomOf="@+id/tv_latitude" />



        <TextView
            android:id="@+id/tv_summary"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:text='@{viewModel.markerObservableField.title + " " + viewModel.markerObservableField.latitude}'
            app:layout_constraintStart_toStartOf="@+id/guideline_left"
            app:layout_constraintTop_toBottomOf="@+id/et_latitude" />


        <android.support.constraint.Guideline
            android:id="@+id/guideline_left"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintGuide_begin="8dp" />
    </android.support.constraint.ConstraintLayout>
</layout>

ViewModel 类

public class AddMarkerViewModel extends AndroidViewModel {

    private MarkerRepository mMarkerRepository;
    public ObservableField<Marker> markerObservableField = new ObservableField<>();


    public AddMarkerViewModel(@NonNull Application application) {
        super(application);

        AppDatabase appDatabase = AppDatabase.getInstance(application.getApplicationContext());

        mMarkerRepository = MarkerRepository
                .getsInstance(MarkerLocalDataSource.getInstance(appDatabase.markerDao(), new AppExecutors()));
        if (markerObservableField.get() == null) {
            Marker marker = new Marker();
            marker.setTitle("New Title");
            markerObservableField.set(marker);
        }
    }


    public long addMarker(Marker marker) {
        return mMarkerRepository.addMarker(marker);
    }
}

Activity 的 onCreate 方法,用于将标记添加到设置值

   protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mBinding = DataBindingUtil.setContentView(this, R.layout.activity_add_marker);
        mAddMarkerViewModel = ViewModelProviders.of(this).get(AddMarkerViewModel.class);
        mBinding.setViewModel(mAddMarkerViewModel);

    }

【问题讨论】:

    标签: android android-databinding android-mvvm


    【解决方案1】:

    为了监听属性变化,你需要扩展BaseObservable

    我认为这里的问题是属性更改不会触发事件,因为您会听到字段更改,即标记对象本身,它保持不变。

    Marker 字段 Latitude 不可观察,这意味着无法检测到它的变化。

    你有两个选择。

    如果您想检测变化,您可以为纬度创建可观察字段。

    public ObservableField<String> latitudeObservableField = new ObservableField<>();
    

    您可以收听字段更改并更新标记对象。

     latitudeObservableField.addOnPropertyChangedCallback(() -> {
     // Update marker object
    })
    

    另一种方法是使Marker 扩展BaseObservable,如附加参考中所述。

    请查看observable objects 上的官方文档。

    【讨论】:

    • 你可能是对的。我只是更改了Marker的属性,这一定是它不更新UI的原因。我已经在另一个活动中将 Marker 与 LiveData> 一起使用,扩展 BaseObservable 会使其占用更多内存,尤其是我将它与列表一起使用。我想我会将 String 和 Integer ObservableFields 添加到 ViewModel 以将更改分发到 UI,但是为每个属性创建一个很麻烦。我一直在寻找更少编码的解决方案。
    • 那么 ObservableField 对数据绑定没用?
    • 据我了解,如果您使用ObservableField ,它适用于原始类型,因为它们是不可变的,您必须直接更新ObservableField。对于使用对象,我认为没有办法检测对象变化。为此,您必须手动通知字段的更改。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-06
    相关资源
    最近更新 更多