Двусторонняя привязка данных конкретного атрибута объекта LiveData - PullRequest
1 голос
/ 05 мая 2019

У меня проблема с двухсторонним связыванием данных с использованием LiveData.У меня есть ViewModel с MutableLiveData<Ingredient> ingredient.В макете XML я хотел бы инициализировать EditText представление с атрибутом ingredient.title.Я попробовал это:

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

    <data>
        <variable
            name="viewModel"
            type="UpdateIngredientViewModel" />
    </data>

    <RelativeLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <EditText
            android:id="@+id/updateIngredient_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:paddingStart="15dp"
            android:paddingEnd="15dp"
            android:text="@={viewModel.ingredient.getValue().title}"
            android:layout_centerHorizontal="true"
            android:layout_below="@+id/updateIngredient_label"
            android:textAlignment="center"
            android:hint="@string/Title"
            android:inputType="text"/>
    </RelativeLayout>
</layout>

Поэтому, используя эту строку android:text="@={viewModel.ingredient.getValue().title}", инициализируйте значение заголовка Ingredient, но если я изменю текст в EditText и поверну экран, например, я не получуизменил значение, но вместо этого инициализировал.Может ли кто-нибудь помочь мне с этим, пожалуйста?Это моя ViewModel:

public class UpdateIngredientViewModel extends AndroidViewModel {

    private MutableLiveData<Ingredient> ingredient;

    public UpdateIngredientViewModel(@NonNull Application application) {
        super(application);
    }

    public LiveData<Ingredient> getIngredient() {
        if (ingredient == null) {
            ingredient = new MutableLiveData<>();
        }
        return ingredient;
    }

    public void setIngredient(Ingredient ingredient) {
            this.ingredient.setValue(ingredient);
    }
}

РЕДАКТИРОВАТЬ

Это класс Ingredient:

public class Ingredient {
    @SerializedName("ingredient_ID")
    private int ingredient_ID;
    @SerializedName("title")
    private String title;

    public Ingredient(int ingredient_ID, String title) {
        this.ingredient_ID = ingredient_ID;
        this.title = title;
    }

    public int getIngredient_ID() {
        return ingredient_ID;
    }

    public void setIngredient_ID(int ingredient_ID) {
        this.ingredient_ID = ingredient_ID;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
}

Я также пытался изменить EditTextатрибут вроде этого android:text="@={viewModel.ingredient.title}", но, похоже, он работает так же, как в оригинальном сообщении.

1 Ответ

0 голосов
/ 05 мая 2019

Двусторонняя привязка данных может обновить вашу модель. Однако в вашем подходе есть две проблемы.

То, с чем вы столкнулись, это то, что MutableLiveData не волшебство, и если вы замените значение, оно с радостью будет следовать приказам. Исходя из вашего комментария , вы заменяли значение в MutableLiveData после изменения конфигурации, и это не учитывалось введенным пользователем.

Другая проблема заключается в том, что хотя MutableLiveData будет содержать ваш пересмотренный Ingredient, любые другие наблюдатели этого MutableLiveData не будут знать об этом изменении. Вы модифицируете модель in situ , а MutableLiveData не знает об этом и не может дать знать другим наблюдателям. Вот почему я предпочитаю использовать MutableLiveData объекты, которые являются как можно более неизменными (например, Kotlin val), и в результате я пропускаю двустороннюю привязку данных.

...