2

У меня есть родительский класс, назовем его BaseViewModel, этот класс можно напечатать и иметь ObservableField того же типа. Например:Двухсторонняя привязка данных с ObservableField <>, set() не работает?

public class BaseViewModel<T> extends BaseObservable { 

    ObservableField<T> value = new ObservableField<>(); 

    public T getValue() { 
     return value.get(); 
    } 

    public void setValue(T value) { 
     this.value.set(value); 
     setHasChanges(value != originalValue); 
    } 

} 

У меня много детей для этого класса. Один из них - StringViewModel, который, как и его имя, дает значение String. Этот дочерний класс переопределяет метод SetValue():

public class StringViewModel extends BaseViewModel<String> { 

    @Override 
    public void setValue(String value) { 
     this.value.set(value); 
     if(value != null && !value.isEmpty()){ 
      setHasChanges(!value.equals(originalValue)); 
     } 
     else if(originalValue == null) 
      setHasChanges(false); 
     else 
      setHasChanges(!originalValue.isEmpty()); 
    } 

    //Other methods ... 

} 

И я получил раскладку, которая использует StringViewModel:

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

    <data> 

     <variable 
      name="viewModel" 
      type="com.myproject.viewmodels.StringViewModel" /> 

    </data> 

    <EditText 
     android:id="@+id/value" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 

     android:clickable="@{viewModel.editable}" 
     android:cursorVisible="@{viewModel.editable}" 

     android:ellipsize="end" 
     android:focusable="@{viewModel.editable}" 
     android:focusableInTouchMode="@{viewModel.editable}" 
     android:inputType="textMultiLine|textNoSuggestions" 

     android:text="@={viewModel.value}" 
     app:setError="@{viewModel.error}" 

     tools:text="Dupont" /> 

    <!-- Other layouts ... --> 

Но когда я называю SetValue() метод моего StringViewModel, значение устанавливается в ViewModel, но не на EditText.

Edit: Я должен также сказать, что я добавить свой StringViewModel к моему DataBinding правильно (с использованием DataBindingUtil раздувать мой DataBinding).

myDataBinding.setViewModel(new StringViewModel());

ли кто-то получил объяснение такого поведения?


EDIT

Как сказал @iMDroid, я должен позвонить notifyChange() в моем методе setValue(). I tought ObservableFields делал это для меня, мой плохой.

ответ

2

Я не являюсь экспертом в области двусторонней передачи данных .. но я читал статьи об этом, поэтому вот одно решение, которое может вам помочь.

Предположим, что ваш класс модели заключается в следующем:

public class Echo { 
    public String text; 
} 

И ваш файл макета R.layout.echo

Они говорят, что вы должны установить макет, используя DataBindingUtil класс, а затем объект на котором вы создаете привязку, которая является EchoBinding (автоматически генерируется в соответствии с макетом):

EchoBinding binding = DataBindingUtil.setContentView(
     this, R.layout.echo); 
    binding.setEcho(new Echo()); 

Кроме того, вы можете связать значение вашей EditText с помощью app:binding="@{echo.text}" атрибута.

<EditText 
    android:layout_width=”match_parent” 
    android:layout_height=”wrap_content” 
    android:hint="Text 1" 
    app:binding="@{echo.text}"/> 

И, наконец, добавить notifyChange() к вашему методу setValue().

Обратитесь к этому link за дополнительной информацией.

Вы можете попробовать. Надеюсь, это поможет.

+0

Спасибо за помощь, но поскольку я редактировал свой вопрос, я забыл упомянуть об этом. На самом деле я правильно добавил свою переменную в DataBinding, используя DataBindingUtil. – MHogge

+0

Даже я отредактировал свой ответ .. Вы пытались добавить notifyChange()? – iMDroid

+1

Хорошая работа! Я думал, потому что это ObservableField, я ничего не должен был уведомлять, я плохо. Спасибо за помощь, я приму это как ответ. – MHogge

0

Добавление StringViewModel к макету недостаточно. В onCreate() или onCreateView() в зависимости от того, что вы используете (Activity или Fragment), вы должны указать свой DataBinding использовать определенный класс StringViewModel.

в OnCreate(), вы хотите сделать что-то подобное,

dataBinding.viewModel = новый StringViewModel();

Теперь dataBinding знает, что вы имеете в виду, и теперь они подключены.

Я считаю, что вы настроили привязку данных.

+0

Да, я установил StringViewModel в свой DataBinding. Извините, я обновлю свой вопрос, чтобы добавить эту информацию. – MHogge