2016-06-27 1 views
3

EditText에 사용자 이름을 입력하고 TextView 안에 Hello {name}을 표시하고 싶습니다. TextView의 텍스트를 관찰 가능 속성 (user.firstName)으로 설정하면 텍스트가 업데이트됩니다. 모델의 toString() 메소드에 텍스트를 설정하더라도 여전히 정상적으로 작동합니다. 그러나 대신 viewModel.hello을 사용하면 텍스트가 업데이트되지 않습니다. 내가 뭘 놓치고 있니?Android : 데이터 바인딩 텍스트가 업데이트되지 않음

모델 :

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

뷰 모델은 :

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

레이아웃 :

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

답변

6

하나의 문제는 당신의 ViewModel 안녕하세요 변경 때문에, 관찰되지 않는 것입니다()는하지 않습니다 모델에 반영됩니다. 관찰 할 수있는 단일 필드이기 때문에 Hello 문자열에 ObservableField를 사용할 수도 있지만 Observable ViewModel을 사용하여이를 보여줍니다.

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() { ... } 
    }; 
} 

}

그러나 나는 뷰 모델은 관찰 가능한 만드는 걱정 직접 XML의 사용자에 대한 변경 사항을 듣고하지하는 것이 훨씬 쉬울 것이라고 생각 :

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

을 그리고 당신이 가진 것 문자열 리소스 :

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

안녕하세요, 제발 내 질문 좀 봐주세요 https://stackoverflow.com/q/45143721/5214893 –