Как динамически изменять видимость представления с помощью привязки данных Android

Я пытаюсь скрыть/показать одно простое представление, используя привязку данных. У меня есть вызов API, и я должен показать один индикатор выполнения, пока происходит вызов API. Как только я получу ответ, я должен отклонить этот прогресс и отобразить данные. Я попытался динамически изменить видимость индикатора выполнения, используя привязку данных. Но ничего не происходит. Только в первый раз видимость прогресбара устанавливается в соответствии с переменной привязки. он не обновляется динамически, поскольку я обновляю переменную привязки.

Ниже приведен мой пример кода для того же

Мероприятия:

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>

а также в build.gradle приложения

dataBinding {
    enabled = true
}

Чего здесь не хватает? почему это не работает? Заранее спасибо..


person Community    schedule 29.11.2016    source источник


Ответы (3)


вам нужно уведомить, что значение вашего свойства изменилось, попробуйте это

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

или если вы хотите уведомить об этом только для одной переменной, используйте BR.propertyName

notifyPropertyChanged(BR.loading);
person Ravi    schedule 29.11.2016

Я хочу уточнить, что если вы используете notifyPropertyChanged(BR._all);, он будет уведомлять все наблюдаемые объекты без необходимости.

Вместо этого следует использовать notifyPropertyChanged(BR.field);, чтобы уведомлять только об измененном элементе.

Если вы хотите model.setLoading(true). Он будет преломляться на связанных взглядах из этого поля.

Обратите внимание, что ваш метод доступа должен быть снабжен атрибутом @Bindable. В противном случае класс BR не будет иметь имя вашего поля.

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

public void setLoading(boolean isLoading ) {
    this.isLoading = isLoading ;
    notifyPropertyChanged(BR.isLoading );
}
person Khemraj Sharma    schedule 09.08.2018

добавьте <import type="android.view.View" /> поверх вашего файла XML. Результат решения будет выглядеть следующим образом

<data>
    <import type="android.view.View" />
    <variable
        name="obj"
        type="com.you.modal.class" />
</data>


 <import type="android.view.View" />
person rinkesh    schedule 06.09.2018