J'utilise
<ExpandableListView
Android:id="@+id/listView"
Android:layout_width="match_parent"
Android:layout_height="match_parent" >
</ExpandableListView>
je veux ajouter une diapositive d'animation pour l'enfant lorsque l'onclique parent. Alors, comment faire?
Mise à jour finale
Cela fait un bon moment que j'ai écrit cette réponse. Depuis lors, beaucoup de choses ont changé. Le plus grand changement est avec l'introduction de RecyclerView
qui facilite l'animation d'une liste ou d'une grille. Je vous recommande fortement de passer à RecyclerView
s si vous le pouvez. Pour ceux qui ne le peuvent pas, je vais voir ce que je peux faire pour corriger les bugs de ma bibliothèque.
Réponse originale
En fait, je n'aime pas l'implémentation populaire d'une ExpandableListView animée qui utilise simplement une ListView avec une animation développée car dans mon cas d'utilisation, chacun de mes groupes avait beaucoup d'enfants, donc il n'était pas possible d'utiliser une ListView normale comme enfant les vues ne seront pas recyclées et l'utilisation de la mémoire sera énorme avec de mauvaises performances. Au lieu de cela, j'ai opté pour une approche beaucoup plus difficile mais plus évolutive et flexible.
J'ai étendu la classe ExpandableListView et remplacé les fonctions onCollapse et onExpand, j'ai également créé une sous-classe d'un BaseExpandableListAdapter appelé AnimatedExpandableListAdapter. À l'intérieur de l'adaptateur, j'ai remplacé la fonction getChildView et rendu la fonction finale afin que la fonction ne puisse pas être à nouveau remplacée. Au lieu de cela, j'ai fourni une autre fonction appelée getRealChildView pour les sous-classes à remplacer pour fournir une véritable vue enfant. J'ai ensuite ajouté un indicateur d'animation à la classe et demandé à getChildView de renvoyer une vue factice si l'indicateur d'animation était défini et la vue réelle si l'indicateur n'était pas défini. Maintenant, avec le décor, je fais ce qui suit pour onExpand:
notifyDataSetChanged()
(force l'adaptateur à appeler getChildView()
pour toutes les vues à l'écran).onDraw()
.notifyDataSetChanged()
.Enfin, avec tout cela fait, j'ai pu non seulement obtenir l'effet d'animation souhaité mais aussi la performance souhaitée car cette méthode fonctionnera avec un groupe de plus de 100 enfants.
Pour l'animation de repli, un peu plus de travail doit être fait pour que tout cela soit configuré et fonctionne. En particulier, lorsque vous remplacez onCollapse, vous ne voulez pas appeler la fonction parent car elle réduira le groupe immédiatement, vous laissant aucune chance de jouer une animation. Au lieu de cela, vous voulez appeler super.onCollapse à la fin de l'animation de repli.
MISE À JOUR:
J'ai passé du temps ce week-end à réécrire mon implémentation de cette AnimatedExpandableListView et je publie la source avec un exemple d'utilisation ici: https://github.com/idunnololz/AnimatedExpandableListView/
La solution @idunnololz fonctionne très bien. cependant je voudrais ajouter du code pour réduire le groupe précédemment développé.
private int previousGroup=-1;
listView.setOnGroupClickListener(new OnGroupClickListener() {
@Override
public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
// We call collapseGroupWithAnimation(int) and
// expandGroupWithAnimation(int) to animate group
// expansion/collapse.
if (listView.isGroupExpanded(groupPosition)) {
listView.collapseGroupWithAnimation(groupPosition);
previousGroup=-1;
} else {
listView.expandGroupWithAnimation(groupPosition);
if(previousGroup!=-1){
listView.collapseGroupWithAnimation(previousGroup);
}
previousGroup=groupPosition;
}
return true;
}
});
animateLayoutChanges adds auto-animation
<ExpandableListView
Android:animateLayoutChanges="true"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent"/>
La solution @idunnololz fonctionne très bien, mais j'ai rencontré un comportement étrange avec ma disposition personnalisée pour le groupe. L'opération d'expansion n'a pas été exécutée correctement, mais l'effondrement a parfaitement fonctionné. J'ai importé son projet de test et cela a très bien fonctionné, j'ai donc réalisé que le problème venait de ma mise en page personnalisée. Cependant, lorsque je n'ai pas pu localiser le problème après une enquête, j'ai décidé de décommenter ces lignes de code dans son AnimatedExpandListView:
if (lastGroup && Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
return expandGroup(groupPos, true);
}
qui a causé le problème (mon application est destinée à Android 4.0+).