web-dev-qa-db-fra.com

Comment modifier de manière dynamique la visibilité d'une vue à l'aide de la liaison de données Android

J'essaie d'obtenir une vue/masquage simple en utilisant la liaison de données. J'ai un appel api et je dois afficher une barre de progression pendant l'appel api. Une fois que je reçois la réponse, il faut ignorer cette progression et afficher les données. J'ai essayé de changer la visibilité de progressbar de manière dynamique en utilisant la liaison de données. Mais rien ne se passe. Ce n'est que pour la première fois que la visibilité de Progresbar est définie en fonction de la variable de liaison. sa mise à jour pas dynamiquement comme je mets à jour la variable de liaison. 

voici mon exemple de code pour le même

Activité:

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>

et aussi dans build.gradle de l'application

dataBinding {
    enabled = true
}

Qu'est-ce qui manque ici? pourquoi ça ne marche pas? Merci d'avance..

6
user4489210

vous devez notifier que la valeur de votre propriété a changé, essayez ceci

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

ou si vous souhaitez le notifier uniquement pour une variable, utilisez BR.propertyName

notifyPropertyChanged(BR.loading);
6
Ravi Rupareliya

Je tiens à préciser que si vous utilisez notifyPropertyChanged(BR._all);, il avertira inutilement tous les observables.

Vous devez utiliser notifyPropertyChanged(BR.field); à la place pour notifier uniquement l'élément modifié.

Si vous voulez model.setLoading(true). Il va réfracter les vues liées de ce champ.

Notez que votre accesseur doit être annoté avec l'attribut @Bindable. Sinon, la classe BR n'aura pas votre nom de champ.

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

public void setLoading(boolean isLoading ) {
    this.isLoading = isLoading ;
    notifyPropertyChanged(BR.isLoading );
}
0
Khemraj

ajouter <import type="Android.view.View" /> au-dessus de votre solution de résultat de fichier XMl sera comme suit

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


 <import type="Android.view.View" />
0
rinkesh