Srt Srt - 9 days ago 6
Android Question

How to dynamically change view visibility using android data binding

I'm trying to achieve one simple view hide/show using data binding. I have an api call and I have to show one progressbar while the api call is going on. Once I get the response have to dismiss this progress and display the data. I tried to change the visibility of progressbar dynamically using data binding. But nothing happens. Only for the first time the progresbar visibility is set according to the binding variable. its not dynamically updating as I update the binding variable.

following is my sample code for the same

Activity:

public class MainActivity extends AppCompatActivity {

private static final String TAG = MainActivity.class.getSimpleName();

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

findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
loadData(viewmodel);
}
});
}

private void loadData(final ViewModel viewmodel) {
viewmodel.setLoading(true);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
Log.d(TAG, "Loading finished");
viewmodel.setLoading(false);
}
}, 2000);
}
}


ViewModel:

import android.databinding.BaseObservable;
import android.databinding.Bindable;

public class ViewModel extends BaseObservable {

private boolean isLoading;
private String data;


@Bindable
public String getData() {
return data;
}

public void setData(String data) {
this.data = data;
}

@Bindable
public boolean isLoading() {
return isLoading;
}

public void setLoading(boolean loading) {
isLoading = loading;
}
}


activity_main.xml

<?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>
<import type="android.view.View"/>
<variable name="viewmodel" type="com.test.databindnig.ViewModel"/>
</data>
<LinearLayout
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.test.databindnig.MainActivity">

<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="@{viewmodel.isLoading ? View.VISIBLE : View.GONE}"/>
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{viewmodel.data}"
android:visibility="@{viewmodel.isLoading ? View.GONE : View.VISIBLE}"/>


<Button
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Load data"/>
</LinearLayout>
</layout>


and also in the app's build.gradle

dataBinding {
enabled = true
}


What is missing over here? why doesn't it work? Thanks in advance..

Answer

you need to notify that your property value is changed, try this

public void setLoading(boolean loading) {
    isLoading = loading;
    notifyPropertyChanged(BR._all);
}