2017-08-10 2 views
0

Ich spiele mit Android, das hat nicht wirklich einen Zweck, es ist nur Dinge zu entdecken.Android MVVM mit Datenbindung

So habe ich eine textWatcher und 2 editText-Box, wie kann ich die Farbe des Textes ändern, wenn der Benutzer den Text ändert?

Zum Beispiel sagen wir, dass wenn der Benutzer etwas anderes als einen Buchstaben setzt, der Text rot sein muss.

Für Leistungsproblem (ist das relevant?) Ich möchte nur einen TextWatcher für alle Felder im Formular haben, die die gleichen Validierungsregeln benötigen (jedes Tutorial, das ich im Internet finde, hat 1 Beobachter pro Feld, vielleicht auch dort) ist ein Grund dafür)

Zuerst wollte ich android:addTextChangedListener= verwenden, aber dies sendet nicht das Edittext-Objekt an den Beobachter, so weiß ich, dass 'ein Feld' hat sich geändert, aber nicht welche.

Ich habe dies:

Blick (3 Feld, 2 Text und 1 numerische)

<?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); 
    } 

} 

Eltern der Haupttätigkeit:

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; 
    } 

} 

und BasicForm obj ect für Datenbindung:

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); 
    } 

} 

Also im Grunde, was ich will, ist nur ein „charOnlyTextWatcher“, die ich in der XML assoziieren kann und dann in seinen onChange() -Methode kann auf dem Anrufer (EditText Objekt handeln, das die onChange ausgelöst())

Mache ich etwas völlig nutzlos? falsch?

Danke.

Antwort

0

Zum Beispiel, wenn der Benutzer etwas anderes als einen Brief setzen, dann muss der Text rot sein.

Lassen Sie uns zunächst die Ansichtsmodell zusammensetzen:

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

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

Nun, da Sie die Eingabe Änderungen gerade hören und eine Eigenschaftsänderung verursacht, lassen Sie uns die layout.xml komponieren:

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

Sie sind bereit zu gehen, kein Code mehr benötigt.
Hoffe es hilft.