2017-09-17 11 views
1

Fondamentalement, mon ViewModel tient la POJO suivante comme MutableLiveData:Existe-t-il un moyen d'observer la taille d'un Arraylist lors de son changement via la liaison de données?

public class SubredditAddition { 

    private final ArrayList<Keyword> mKeywords = new ArrayList<>(); 

} 

Et je veux une vue de disparaître si mKeyword.size() > 0

Actuellement, j'ai la ligne suivante à mon avis:

android:visibility="@{viewModel.subredditAddition.keywords.size() == 0 ? View.GONE : View.VISIBLE}" 

Toutefois, les modifications apportées à la taille du tableau mKeywords n'affectent pas la visibilité de la vue. Comment puis-je faire en sorte que la vue réagisse à la taille de ArrayList en temps réel?

Mise à jour:

Ma classe SubredditAddition utilise maintenant ObservableArraylist, comme ceci:

public class SubredditAddition { 

    private final ObservableArrayList<Keyword> mKeywords = new ObservableArrayList<>(); 

} 

Mon ViewModel ressemble à ceci, la tenue d'une SubredditAddition dans un MutableLiveData:

public class SubredditSelectionViewModel extends AndroidViewModel { 

    private MutableLiveData<SubredditAddition> mSubredditAddition = new MutableLiveData<>(); 

    public SubredditSelectionViewModel(Application application) { 
     super(application); 

     mSubredditAddition.setValue(new SubredditAddition()); 
    } 
} 

Et mon Fragment a le code suivant pour mettre à jour les mots-clés:

public class SubredditSelectionFragment extends Fragment { 

    private void saveTag(Keyword newKeyword) { 
     SubredditSelectionViewModel viewModel = 
       ViewModelProviders.of(this).get(SubredditSelectionViewModel.class); 

     ObservableArrayList<Keyword> keywords = viewModel.getSubredditAddition().getKeywords(); 

     keywords.add(newKeyword); 
    } 
} 

Mon point de vue XML ressemble à ceci:

<RelativeLayout .... 
      android:visibility="@{viewModel.subredditAddition.keywords.size() == 0 ? View.VISIBLE : View.GONE}"> 

Cependant, mon interface utilisateur ne fonctionne toujours pas mis à jour une fois que j'ajouter un mot-clé via la méthode saveKeyword() dans mon Fragment. Comment puis-je réparer cela?

Répondre

3

Oui. ArrayList lui-même n'est pas observable. Soit vous voulez pousser un changement dans votre registre si vous avez ajouté/supprimé des éléments, ou vous utilisez un ObservableArrayList à la place.

Il se comporte comme le ArrayList et you'r en mesure d'utiliser get() et set()

public class SubredditAddition { 
    public final ObservableList<Keyword> mKeywords = new ObservableArrayList<>(); 
} 

Make it public si vous ne fournissez pas getter et setters.

Même si la solution ci-dessus peut fonctionner, elle n'est pas recommandée car elle ne sera pas mise à jour si un élément de la liste est mis à jour mais pas la liste elle-même.

Une meilleure solution consiste à créer un ObservableInt ou un ObservableBoolean et à mettre à jour cette onec. Le setter Listes a été appelé.

Exemple:

ObservableInt listVisibility = new ObservableInt(View.GONE); 

public void setListData(List<Keyword> data) { 
    // update your list 
    listVisibility.set(data.size() > 0 ? View.VISIBLE : View.GONE); 
} 

et enfin dans votre mise en page:

android:visibility="@{viewModel.listVisibility}" 
+0

J'ai essayé, mais il n'y avait toujours pas de mise à jour de l'interface utilisateur. Est-ce que SubredditAddition doit étendre BaseObservable ou quelque chose? – BeardMagician

+0

ObservableList notifier la vue onec il a changé (set() appelé). Assurez-vous que c'est public et vous n'avez pas de getter/setter. Faites attention: il ne vous avertit que si votre liste ADD ou REMOVE éléments. Voulez-vous écouter les changements dans le mot-clé aussi? Si oui, je mets à jour la réponse pour une solution –

+0

Je veux notifier quand un élément est ajouté ou supprimé. En ce moment je fais list.add().Suis-je censé utiliser list.set() à la place? – BeardMagician