带有数据绑定的Android MVVM

时间:2017-08-10 14:32:13

标签: java android mvvm

我正在玩android,这并不是真正的目的,只是为了发现内容。

所以我有一个textWatcher和2个editText框,当用户更改文本时,如何更改文本的颜色?

例如,假设用户输入的内容不是字母,则文本必须为红色。

对于性能问题(这是相关的吗?)我想只有一个textWatcher用于需要相同验证规则的表单中的所有字段(我在互联网上找到的每个教程每个字段有1个观察者,也许有这个原因)

起初我想使用android:addTextChangedListener=,但这不会将edittext对象发送给观察者,所以我知道'一个字段'已经改变但不是哪一个。

我有这个:

查看(3个字段,2个文本和1个数字)

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable
            name="basicForm"
            type="com.example.mvvm.databinding.BasicForm" />
    </data>

<android.support.constraint.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/constraint"
    tools:context="com.example.mvvm.databinding.MainActivity">

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical"
        tools:layout_editor_absoluteX="0dp"
        tools:layout_editor_absoluteY="0dp">

        <EditText
            android:id="@+id/nameField"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="241dp"
            android:ems="10"
            android:hint="@{basicForm.fieldName}"
            android:inputType="textPersonName"
            android:layout_alignParentTop="true"
            android:layout_alignStart="@+id/lastnameField" />

        <EditText
            android:id="@+id/lastnameField"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ems="10"
            android:textColor="#00FF00"
            android:hint="@{basicForm.fieldLastName}"
            android:inputType="textPersonName"
            android:layout_marginBottom="81dp"
            android:layout_alignBottom="@+id/nameField"
            android:layout_centerHorizontal="true" />


        <EditText
            android:id="@+id/phoneField"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignStart="@+id/nameField"
            android:layout_below="@+id/nameField"
            android:layout_marginTop="35dp"
            android:ems="10"
            android:hint="@{basicForm.fieldPhone}"
            android:inputType="textPersonName" />

    </RelativeLayout>

</android.support.constraint.ConstraintLayout>
</layout>

MainActivity:

package com.example.mvvm.databinding;

import android.databinding.DataBindingUtil;
import android.os.Bundle;

import com.example.mvvm.databinding.databinding.ActivityMainBinding;

public class MainActivity extends FormActivity {

    ActivityMainBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        final BasicForm bf = new BasicForm();
        bf.setFieldPhone("06XXXXXXXX");
        bf.setFieldName("Name");
        bf.setFieldLastName("Last Name");
        bf.setStringWatcher(getStringWatcherInstance());
        bf.setPhoneWatcher(getPhoneWatcherInstance());
        binding.setBasicForm(bf);
    }

}

主要活动的主管:

package com.example.mvvm.databinding;

import android.support.v7.app.AppCompatActivity;
import android.text.Editable;
import android.text.TextWatcher;

import java.util.regex.Pattern;

public class FormActivity extends AppCompatActivity {

    private static TextWatcher stringWatcherInstance = null;
    private static TextWatcher phoneWatcherInstance = null;

    public boolean stringContainsOnlyChar(String s) {
        if(! Pattern.matches(".*[a-zA-Z]+.*[a-zA-Z]", s)) {
            return true;
        }
        return false;
    }

    public synchronized TextWatcher getStringWatcherInstance() {
        if(stringWatcherInstance == null) {
            stringWatcherInstance = new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {

                }

                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {
                    if (stringContainsOnlyChar(s.toString())) {
                        //set color of calling edit box to black
                    }
                    //set color of calling edif box to red

                }

                @Override
                public void afterTextChanged(Editable s) {

                }
            };

        }
        return stringWatcherInstance;
    }

    public synchronized TextWatcher getPhoneWatcherInstance() {
        if(phoneWatcherInstance == null) {
            phoneWatcherInstance = new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {

                }

                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {

                }

                @Override
                public void afterTextChanged(Editable s) {

                }
            };

        }
        return phoneWatcherInstance;
    }

}

和用于数据绑定的BasicForm对象:

package com.example.mvvm.databinding;
import android.databinding.BaseObservable;
import android.databinding.Bindable;
import android.text.TextWatcher;

public class BasicForm extends BaseObservable {

    private String fieldName;
    private String fieldLastName;
    private String fieldPhone;

    public BasicForm() {}

    @Bindable
    public String getFieldName() {

        return fieldName;
    }

    public void setFieldName(String FieldName) {
        this.fieldName = FieldName;
        notifyPropertyChanged(BR.fieldName);
    }

    @Bindable
    public String getFieldLastName() {
        return fieldLastName;
    }

    public void setFieldLastName(String fieldLastName) {
        this.fieldLastName = fieldLastName;
    }

    @Bindable
    public String getFieldPhone() {
        return fieldPhone;
    }

    public void setFieldPhone(String fieldPhone) {
        this.fieldPhone = fieldPhone;
        notifyPropertyChanged(BR.fieldPhone);
    }

}

基本上我想要的只是一个“charOnlyTextWatcher”,我可以在xml中关联然后在它的onChange()方法中可以对调用者(触发onChange()的edittext对象)

我做的事总无用吗?错?

感谢。

1 个答案:

答案 0 :(得分:0)

  

例如,假设用户输入的内容不是a   信,那么文字必须是红色的。

首先让我们编写ViewModel:

@Bindable public Color getTextColor(){
      return mSomeText.length() == 1? Color.Black : Color.Red; 
}

public void onInputChanged(Editable editable){
     mSomeText = editable.toString();
     notifyPropertyChanged(BR.textColor); 
}

现在您正在侦听输入更改并导致更改属性,让我们编写layout.xml:

    <EditText
        ...
        android:afterTextChanged="{@viewModel::onInputChanged}" 
        android:textColor="@{viewModel.textColor}" />

您已准备就绪,无需更多代码 希望它有所帮助。