我正在玩 android,这没有真正的目的,只是为了发现东西。
所以我有一个textWatcher和2个editText框,当用户更改文本时如何更改文本的颜色?
例如,假设如果用户输入字母以外的内容,则文本必须为红色。
对于性能问题(这相关吗?)我希望表单中需要相同验证规则的所有字段只有一个 textWatcher(我在互联网上找到的每个教程每个字段都有 1 个观察者,也许这是有原因的)
一开始我想使用 android:addTextChangedListener=
但这不会将 edittext 对象发送给观察者,所以我知道“一个字段”已更改,但不知道是哪个字段。
我有这个:
View (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>
主要 Activity :
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);
}
}
主要 Activity 的父级:
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;
}
}
和用于数据绑定(bind)的 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);
}
}
所以基本上我想要的只是一个可以在 xml 中关联的“charOnlyTextWatcher”,然后在它的 onChange() 方法中可以作用于调用者(触发 onChange() 的 edittext 对象)
我是不是在做一些毫无用处的事情?错了?
谢谢。
最佳答案
For example let's say that if the user put something else than a letter then the text has to be red.
首先让我们构建 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}" />
您已准备好开始,无需更多代码。
希望对您有所帮助。
关于java - Android MVVM 与数据绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45616606/