211 votes

Comment Animer l'Ajout ou la Suppression d'Android ListView Lignes

Dans iOS, il est très facile et puissant de la facilité à animer l'ajout et la suppression de la UITableView lignes, voici un clip d'une vidéo youtube montrant l'animation par défaut. Notez comment les environs lignes effondrement sur la ligne supprimée. Cette animation permet aux utilisateurs de garder une trace de ce qui a changé dans une liste, et la liste qu'ils étaient à la recherche à un moment où les données ont changé.

Depuis que j'ai été en développement sur Android, j'ai trouvé aucun équivalent facilité à animer des lignes individuelles dans un TableView. Appelant notifyDataSetChanged() sur ma Carte causes de la liste à immédiatement mettre à jour son contenu avec de nouvelles informations. J'aimerais vous montrer une simple animation d'une nouvelle ligne, poussant dans coulissantes ou lorsque les données changent, mais je ne trouve pas toutes documentées façon de le faire. Il ressemble à LayoutAnimationController peut détenir une clé pour obtenir que cela fonctionne, mais quand j'ai mis un LayoutAnimationController sur mon ListView (similaire à ApiDemo de LayoutAnimation2) et de supprimer des éléments de ma carte après que la liste est affichée, les éléments disparaissent immédiatement au lieu d'obtenir de l'animation.

J'ai aussi essayé des choses comme les suivantes pour animer un élément lorsqu'il est retiré:

@Override
protected void onListItemClick(ListView l, View v, final int position, long id) {
    Animation animation = new ScaleAnimation(1, 1, 1, 0);
    animation.setDuration(100);
    getListView().getChildAt(position).startAnimation(animation);
    l.postDelayed(new Runnable() {
        public void run() {
            mStringList.remove(position);
            mAdapter.notifyDataSetChanged();
        }
    }, 100);
}

Cependant, les lignes entourant l'animation de ligne ne pas déplacer la position jusqu'à ce qu'ils sautent de leurs nouvelles positions notifyDataSetChanged() est appelé. Il semble ListView n'a pas de mise à jour de sa mise en page une fois que ses éléments ont été placés.

Lors de l'écriture de ma propre mise en œuvre/fourche de ListView a traversé mon esprit, cela semble être quelque chose qui ne devrait pas être si difficile.

Merci!

124voto

OAK Points 782
Animation anim = AnimationUtils.loadAnimation(
                     GoTransitApp.this, android.R.anim.slide_out_right
                 );
anim.setDuration(500);
listView.getChildAt(index).startAnimation(anim );

new Handler().postDelayed(new Runnable() {

    public void run() {

        FavouritesManager.getInstance().remove(
            FavouritesManager.getInstance().getTripManagerAtIndex(index)
        );
        populateList();
        adapter.notifyDataSetChanged();

    }

}, anim.getDuration());

de haut en bas de l'animation d'utilisation :

<set xmlns:android="http://schemas.android.com/apk/res/android">
        <translate android:fromYDelta="20%p" android:toYDelta="-20"
            android:duration="@android:integer/config_mediumAnimTime"/>
        <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
            android:duration="@android:integer/config_mediumAnimTime" />
</set>

9voto

dimetil Points 1327

Jetez un oeil à la solution Google. Voici une méthode de suppression seulement.

ListViewRemovalAnimation projet de code et la Vidéo de démonstration

Il a besoin d'Android 4.1+ API (16). Mais nous avons 2014 à l'extérieur.

2voto

Mannaz Points 6351

Depuis ListViews sont hautement optimisé je pense que ce n'est pas possible de accieve. Avez-vous essayé de créer votre "ListView" par le code (c'est à dire par le gonflage de vos lignes de xml et en les ajoutant à un LinearLayout) et les animer?

2voto

Sam Dufel Points 10154

Avez-vous pensé à l'animation d'un balayage vers la droite? Vous pourriez faire quelque chose comme le dessin progressivement, une plus grande barre blanche dans la partie supérieure de l'élément de la liste, puis en le retirant de la liste. Les autres cellules serait encore jerk en place, mais ce serait mieux que rien.

2voto

jkschneider Points 4014

J'ai bidouillé un autre moyen de le faire sans avoir à manipuler la vue liste. Malheureusement, régulière Android Animations semblent manipuler le contenu de la ligne, mais sont inefficaces à la réduction de la vue. Donc, d'abord considérer ce gestionnaire:

private Handler handler = new Handler() {
@Override
public void handleMessage(Message message) {
    Bundle bundle = message.getData();

    View view = listView.getChildAt(bundle.getInt("viewPosition") - 
        listView.getFirstVisiblePosition());

    int heightToSet;
    if(!bundle.containsKey("viewHeight")) {
    Rect rect = new Rect();
    view.getDrawingRect(rect);
    heightToSet = rect.height() - 1;
    }
    else
    heightToSet = bundle.getInt("viewHeight");

    setViewHeight(view, heightToSet);

    if(heightToSet == 1)
    return;

    Message nextMessage = obtainMessage();
    bundle.putInt("viewHeight", (heightToSet - 5 > 0) ? heightToSet - 5 : 1);
    nextMessage.setData(bundle);
    sendMessage(nextMessage);
}

Ajouter cette collection à votre Liste de carte:

private Collection<Integer> disabledViews = new ArrayList<Integer>();

et d'ajouter

public boolean isEnabled(int position) {
   return !disabledViews.contains(position);
}

Ensuite, l'endroit où vous souhaitez masquer une ligne, ajouter ceci:

Message message = handler.obtainMessage();
Bundle bundle = new Bundle();
bundle.putInt("viewPosition", listView.getPositionForView(view));
message.setData(bundle);
handler.sendMessage(message);    
disabledViews.add(listView.getPositionForView(view));

Ça y est! Vous pouvez modifier la vitesse de l'animation en modifiant le nombre de pixels qu'il prenne de la hauteur à la fois. Pas de réel sophistiqué, mais il fonctionne!

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X