2016-06-27 8 views
3

Ich möchte, dass der Benutzer seinen Namen in eine EditText eingeben und Hello {name} in einer TextView anzeigen. Wenn ich den Text der TextView als die beobachtbare Eigenschaft (user.firstName) festlegen, wird der Text aktualisiert. Selbst wenn ich den Text auf die toString() Methode des Modells setze, funktioniert es immer noch gut. Wenn ich stattdessen stattdessen viewModel.hello verwende, wird der Text nicht aktualisiert. Was vermisse ich?Android: Datenbindungstext wird nicht aktualisiert

Modell:

public class User extends BaseObservable { 
    public String firstName; 
    public String lastName; 

    public User(String firstName, String lastName) { 
     this.firstName = firstName; 
     this.lastName = lastName; 
    } 

    @Bindable 
    public String getFirstName() { 
     return firstName; 
    } 

    public void setFirstName(String firstName) { 
     this.firstName = firstName; 
     notifyPropertyChanged(BR.firstName); 
    } 

    @Bindable 
    public String getLastName() { 
     return lastName; 
    } 

    public void setLastName(String lastName) { 
     this.lastName = lastName; 
     notifyPropertyChanged(BR.lastName); 
    } 

    @Override 
    public String toString() { 
     return getFirstName() + " " + getLastName(); 
    } 
} 

Ansichtsmodell:

public class ViewModel { 
    public User user; 

    public ViewModel() { 
     user = new User("", ""); 
    } 

    public String hello() { 
     return "Hello " + user.toString(); 
    } 

    public TextWatcher userNameTextWatcher() { 
     return new TextWatcher() { 
      @Override 
      public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { 

      } 

      @Override 
      public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { 

      } 

      @Override 
      public void afterTextChanged(Editable editable) { 
       if (editable.toString().length() == 0) { 
        user.setFirstName(""); 
        user.setLastName(""); 
        user.notifyChange(); 
        return; 
       } 
       String[] name = editable.toString().split(" "); 
       if (name.length == 1) { 
        user.setFirstName(name[0]); 
        user.setLastName(""); 
        user.notifyChange(); 
        return; 
       } 
       String firstName = name[0] + " "; 
       for (int i = 0; i < name.length - 2; i++) { 
        firstName = firstName + " " + name[i] + " "; 
       } 
       user.setFirstName(firstName); 
       user.setLastName(name[name.length - 1]); 
       user.notifyChange(); 
      } 
     }; 
    } 
} 

Layout:

<data> 
    <variable 
     name="viewModel" 
     type=".ViewModel"/> 
</data> 

<TextView 
     android:id="@+id/textView" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     tools:text="@{viewModel.hello}"/> 

    <EditText 
     android:id="@+id/editText" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_below="@+id/textView" 
     android:layout_marginTop="8dp" 
     app:addEditTextWatcher="@{viewModel.userNameTextWatcher}"/> 

Antwort

6

Ein Problem ist, dass Ihr Ansichtsmodell nicht beobachtbar ist, so Änderungen an hallo() nicht sich im Modell widerspiegeln. Da es ein einzelnes Feld ist, das beobachtbar ist, können Sie auch ein ObservableField für die Hallo-Zeichenfolge verwenden, aber ich werde es mit einem Observable ViewModel demonstrieren.

public class ViewModel extends BaseObservable { 
    public final User user; 

    public ViewModel() { 
     user = new User("", ""); 
     user.addOnPropertyChangedCallback(new OnPropertyChangedCallback { 
      @Override 
      public void onPropertyChanged(Observable sender, int property) { 
       if (property == BR.firstName || property == BR.lastName) { 
        notifyPropertyChanged(ViewModel.this, BR.hello); 
       } 
      } 
     }); 
    } 

    @Bindable 
    public String hello() { 
     return "Hello " + user.toString(); 
    } 

    public TextWatcher userNameTextWatcher() { 
     return new TextWatcher() { ... } 
    }; 
} 

}

Aber ich denke, es wäre viel einfacher sein, um Änderungen an Benutzer in den XML-Daten direkt zu hören und sich keine Sorgen darum, Ansichtsmodell beobachtbare:

<data> 
    <variable 
     name="viewModel" 
     type=".ViewModel"/> 
</data> 

<TextView 
    android:id="@+id/textView" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    tools:text="@{@string/hello(viewModel.user.firstName, viewModel.user.lastName)}"/> 

<EditText 
    android:id="@+id/editText" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_below="@+id/textView" 
    android:layout_marginTop="8dp" 
    app:addEditTextWatcher="@{viewModel.userNameTextWatcher}"/> 

Und du müss eine Zeichenfolge Ressource:

<string name="hello">Hello %1$s %2$s</string> 
+0

Hallo, können Sie bitte einen Blick auf meine Frage https://Stackoverflow.com/q/45143721/5214893 –