3

I am trying to use two-way data binding for editing user data. I am able to show the POJO contents in the view but the changes made by user are not able to capture back with POJO.

public class MainActivity extends AppCompatActivity {

    ActivityMainBinding binding;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        binding  = DataBindingUtil.setContentView(this, R.layout.activity_main);

        User user = new User();
        user.setFirstName("first a");
        user.setLastName("last b");

        binding.setUser(user);
    }
    public void Click(View v){

        //ActivityMainBinding binding = ActivityMainBinding.inflate(getLayoutInflater());
        User user = binding.getUser();

        Toast.makeText(this,user.getFirstName(),Toast.LENGTH_LONG).show();
    }
}

I have tried using a global variable for user, binding too. But when I click the button, it always shows the "first a". The definition for User.java is:

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

    @Bindable
    public String getFirstName(){ return firstName;}
    public void setFirstName(String first) {
        firstName = first;
        notifyPropertyChanged(com.example.ks.myapplication.BR.firstName);
    }
    @Bindable
    public String getLastName(){ return lastName;}
    public void setLastName(String last) {
        lastName = last;
        notifyPropertyChanged(com.example.ks.myapplication.BR.lastName);
    }
}

and the XML: Here, I am trying to display the changes immediately in text views and on button click also.

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable name="user" type="com.example.ks.myapplication.User"/>
    </data>
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/editText2"
            android:text="@{user.firstName}" />

        <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/editText"
            android:text="@{user.lastName}" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="New Button"
            android:id="@+id/button"
            android:layout_gravity="center_horizontal"
            android:onClick="Click" />

        <TextView android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{user.firstName}"/>

        <TextView android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{user.lastName}"/>
    </LinearLayout>
</layout>

Is there anything I am missing?

Krishna Sarma
  • 1,852
  • 2
  • 29
  • 52
  • your POJO has `private` fields for `firstName` and `lastName` - shouldn't you be using your `accessor` and `mutator` methods? I've never used XML databinding before, however it wold seem bad if you can access private fields. – Mark Mar 09 '16 at 11:13
  • This is by design. Source: http://developer.android.com/tools/data-binding/guide.html – Krishna Sarma Mar 09 '16 at 12:25
  • If you look though, they are `public` variables in the example link, not `private` variables as per your POJO? It explains you need to use `accessor` methods if using `private` fields. – Mark Mar 09 '16 at 12:34
  • I think you are referring to first piece of code under Data Object heading. Just below, there is another code, followed by description: `From the perspective of data binding, these two classes are equivalent. The expression @{user.firstName} used for the TextView’s android:text attribute will access the firstName field in the former class and the getFirstName() method in the latter class. Alternatively, it will also be resolved to firstName() if that method exists.` – Krishna Sarma Mar 09 '16 at 12:42

1 Answers1

0

Two way data binding facility is still under implementation.
You have upgrade project to latest alpha build (com.android.tools.build:gradle:2.1.0-alpha3) and have to use @={..} type expression!!
See details at: https://halfthought.wordpress.com/2016/03/23/2-way-data-binding-on-android/

Mr. Oronno
  • 339
  • 4
  • 4