2017-08-10 128 views
0

我正在玩android,這並不是一個真正的目的,它只是發現的東西。Android MVVM與數據綁定

因此,我有一個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 obj ECT數據綁定:

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對象())

我在做一些無用的事嗎?錯誤?

謝謝。

回答

0

例如,假設用戶輸入的不是 字母,那麼文本必須是紅色的。

首先,讓我們組成視圖模型:

@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}" /> 

你是準備好了,不需要更多的代碼。
希望它有幫助。