android viewmodel с / без baseObservable - PullRequest
       12

android viewmodel с / без baseObservable

0 голосов
/ 06 апреля 2020

Я пытался просмотреть модель в android, поэтому для MainViewModel. java Я написал это:


public class MainViewModel extends ViewModel {

    private String textView;
    private String editText;

    //@Bindable
    public String getTextView(){
        return textView;
    }

    private void setTextView(String value){
        textView=value;
    }

    //@Bindable
    public TextWatcher getEditTextWatcher() {
        return new TextWatcher() {
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                setTextView(s.toString());
            }
            ...
        };
    }

}

И в ActivityMain. xml Я написал это:


        <TextView
            android:text="View-Model / Data-Binding"
            android:layout_width="match_parent"
            android:layout_height="40dp"/>

        <TextView
            android:id="@+id/main_text_view"
            android:text="@{mainvm.textView}"
            android:layout_width="match_parent"
            android:layout_height="40dp"/>

        <EditText
            android:id="@+id/main_edit_text"
            app:textChangeListener="@{mainvm.editTextWatcher}"
            android:layout_width="match_parent"
            android:layout_height="40dp"/>

Я получаю 2 ошибки:

Cannot find a setter for <android.widget.EditText app:textChangeListener> that accepts parameter type 'android.text.TextWatcher'

If a binding adapter provides the setter, check that the adapter is annotated correctly and that the parameter type matches.

И,

error: cannot find symbol class ActivityMainBindingImpl

В некоторых статьях используется аннотация @Binable, расширяющая BaseObservable, что не является предметом ViewModel.

Итак, мой вопрос, как я могу решить это?

Ответы [ 2 ]

0 голосов
/ 07 апреля 2020

Вы не можете расширить как BaseObservable, так и ViewModel в одном классе. Вы можете использовать ObservableFields внутри ViewModel.

Вам необходимо использовать Двусторонняя привязка данных , добавив класс, который простирается от BaseObservable

В этом классе создайте поле для текст, который нужно соблюдать; затем аннотируйте его получатель с помощью @Bindable и вызовите notifyPropertyChanged() в его установщике

ViewModel

public class MainViewModel extends ViewModel {

    Observer mObserver = new Observer();

    Observer getObserver() {
        return mObserver;
    }

    public static class Observer extends BaseObservable {
        private String text;

        @Bindable
        public String getText() {
            return text;
        }

        public void setText(String value) {
            text = value;
            notifyPropertyChanged(BR.text);
        }
    }

}

Activity

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityMainBinding mActivityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);

        MainViewModel mViewModel = new ViewModelProvider(this).get(MainViewModel.class);
        mActivityMainBinding.setObserver(mViewModel.getObserver());
    }
}

Макет

<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="observer"
            type="com.zain.android.twowaydatabindingedittextobservable.MainViewModel.Observer" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <TextView
            android:id="@+id/tvName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{observer.text}"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <EditText
            android:id="@+id/etName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@={observer.text}"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/tvName" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

Wi sh, который может помочь вам

0 голосов
/ 06 апреля 2020

Вам необходимо создать BindingAdapter, чтобы правильно использовать DataBinding. Вы можете прочитать более подробно там Например, создать для EditText

@BindingAdapter("addEditTextWatcher")
fun bindEditText(editText: EditText, stringTextWatcher: StringTextWatcher) {
    val string = editText.text.toString()
    stringTextWatcher.setString(editText.text.toString())
    editText.addTextChangedListener(stringTextWatcher)
}

Затем вам нужно создать экземпляр TextWather в вашей ViewModel, чтобы связать его. xml, как это

        <EditText
            android:id="@+id/main_edit_text"
            app:textChangeListener="@{mainvm.editTextWatcher}"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            addIntEditTextWatcher="@{viewModel.yourTextWatcher}"
/>
...