6

Two-way DataBinding in Android

 3 years ago
source link: https://www.ravirupareliya.com/blog/two-way-databinding-in-android/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Home Android / DataBinding Two-way DataBinding in Android

Two-way DataBinding in Android

banner.jpg?fit=750%2C366&ssl=1

In the earlier posts we have seen how to use DataBinding, Setting custom font and Image loading. Today we will discuss about two-way DataBinding.

What is Two-way DataBinding?

Till now we have seen how to set values to xml view, but in controls like EditText we need to fetch value. In simple term two-way DataBinding is setting values to that control and fetching it after having some changes.

ObservableField

ObservableField can be used instead of extending BaseObservable class. ObservableFields are self-contained observable objects that have a single field.

public class User
    public final ObservableField<String> userName =
            new ObservableField<>();
    public final ObservableField<String> password =
            new ObservableField<>();

There is no need to create getter setter methods when we are using ObservableFields. Now attach custom TextWatcher to get values of EditText control.

public TextWatcherAdapter userNameWatcher = new TextWatcherAdapter(userName);
public TextWatcherAdapter passwordWatcher = new TextWatcherAdapter(password);

TextWatcherAdapter is custom class which extends TextWatcher. It will be used to fetch updated value of EditText.

public class TextWatcherAdapter implements TextWatcher {
    public final ObservableField<String> value =
            new ObservableField<>();
    private final ObservableField<String> field;
    private boolean isInEditMode = false;
    public TextWatcherAdapter(ObservableField<String> f) {
        this.field = f;
        field.addOnPropertyChangedCallback(new Observable.OnPropertyChangedCallback(){
            @Override
            public void onPropertyChanged(Observable sender, int propertyId) {
                if (isInEditMode){
                    return;
                value.set(field.get());
    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    @Override public void afterTextChanged(Editable s) {
        if (!Objects.equals(field.get(), s.toString())) {
            isInEditMode = true;
            field.set(s.toString());
            isInEditMode = false;

Layout file is very simple for this, with 2 EditTexts and a button. We need to set addTextChangeListener to bind custom TextWatcher with EditText.

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <data>
        <variable
            name="user"
            type="com.androidgig.logindemo.Model.User"></variable>
        <variable
            name="handler"
            type="com.androidgig.logindemo.Handler.ClickHandler"></variable>
    </data>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:padding="20dp"
        android:orientation="vertical">
        <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="User name"
            android:singleLine="true"
            android:imeOptions="actionNext"
            android:addTextChangedListener="@{user.userNameWatcher}"/>
        <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="Password"
            android:inputType="textPassword"
            android:singleLine="true"
            android:imeOptions="actionDone"
            android:layout_marginTop="10dp"
            android:addTextChangedListener="@{user.passwordWatcher}"/>
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Login"
            android:layout_marginTop="20dp"
            android:onClick="@{handler.onClickLogin}"/>
    </LinearLayout>
</layout>

Here you have noticed handler.onClickLogin in a Button, that is nothing but an interface which we have binded to Button.

public interface ClickHandler {
    void onClickLogin(View view);

Finally we will write our Activity code to perform all the actions. Binding will be same as we have done earlier.

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

we need to set Model/Pojo class to view and set handler for onClick event. Here is full code of our MainActivity.

public class MainActivity extends AppCompatActivity implements ClickHandler {
    ActivityMainBinding binding;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding= DataBindingUtil.setContentView(this, R.layout.activity_main);
        binding.setUser(new User());
        binding.setHandler(this);
    @Override
    public void onClickLogin(View view) {
        User user=binding.getUser();
        if(validate(user))
            Toast.makeText(MainActivity.this,"Hello " + user.userName.get() + " your password is : " + user.password.get(),Toast.LENGTH_SHORT).show();
    private boolean validate(User user)
        if(user.userName.get() == null || user.userName.get().trim().length()<=0)
            Toast.makeText(MainActivity.this,"Please enter username.",Toast.LENGTH_SHORT).show();
            return false;
        else if(user.password.get() == null || user.password.get().trim().length()<=0)
            Toast.makeText(MainActivity.this,"Please enter password.",Toast.LENGTH_SHORT).show();
            return false;
        return true;

With this you are done with your simple login screen using DataBinding.

two-way databinding

Download code

Update :

With the latest update of DataBinding announced in Google I/O16, you will be able to use Two-Way DataBinding with minimal number of code. You don’t need to write those listeners. Here is the thing you need to change in your xml file.

android:text="@={user.name}"

By adding = sign in your expression will support Two-Way DataBinding.

Ravi Rupareliya

He loves to explore new technologies and have worked on Android, React Native, Action on Google and Flutter.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK