Search code examples
javaandroiddata-bindingandroid-databinding

Two-way data binding not working in Android


I know there have been some discussions about this in the past like this one. However, it doesn't seem to be working for me. Here's what I have in my layout:

  <TextView android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@{word.contents}"
        android:id="@+id/wordView"/>
    <EditText android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/wordInput"
        android:text="@={word.contents}"/>

I expect my TextView show the updated text in EditText as I type. But it doesn't happen. I can make it work by implementing my own Text Watchers but I thought the whole point of data-binding was to avoid doing that. Am I missing anything here? Do I need to be doing more? I found some people suggesting to make the data obeservable or bindable but I'd rather not mess up my model objects. Here's my gradle dependency:

classpath 'com.android.tools.build:gradle:2.2.3'

and my app gradle has:

dataBinding {
    enabled = true
}

and in my MainActivity's onCreate:

MainBinding binding = DataBindingUtil.setContentView(this, R.layout.main);
Word word = new Word("Test Word");
binding.setWord(word);

and here's the Word class, a simple POJO:

public class Word {
    private String contents;

    public Word() {
        contents = "";
    }

    public Word(String contents) {
        this.contents = contents;
    }

    public String getContents() {
        return contents;
    }

    public void setContents(String contents) {
        this.contents = contents;
    }
}

Also, I debugged the app leaving a breakpoint in my setContents method. I can see upon changing EditText, code stops at the breakpoint and model actually changes. It just looks like the TextView component doesn't get updated. Any idea?


Solution

  • Update your Java file like,

    MainBinding binding = DataBindingUtil.setContentView(this, R.layout.main);
    Word word = new Word();
    word.setContents("Test Word");
    binding.setWord(word);
    

    Can you update Word class like ,

    public class Word extends BaseObservable {
    private String contents;
    
    public Word() {
        contents = "";
    }
    
    public Word(String contents) {
        this.contents = contents;
    }
    
    @Bindable
    public String getContents() {
        return contents;
    }
    
    public void setContents(String contents) {
        this.contents = contents;
        notifyPropertyChanged(BR.contents);
      }
    }