web-dev-qa-db-fra.com

Animation de la hauteur du conteneur LinearLayout avec ValueAnimator

J'ai un LinearLayout que j'utilise comme conteneur pour certains boutons et textview dont j'aimerais animer la hauteur pour donner une impression de la mise en page glissant vers le bas lorsque l'utilisateur appuie sur un bouton "afficher".

J'ai mis le LinearLayout à layout_height = "0dp" et visibilité = "gone" dans mon xml. Je souhaite ensuite le définir pour qu'il soit visible et quelle que soit la hauteur nécessaire pour envelopper le contenu. Pour le moment, j'ai même des problèmes pour l'animer, quelle que soit la hauteur du contenu de l'enveloppe.

Voici ma méthode d'animation:

private void toggle(final LinearLayout v) {
    v.setVisibility(View.VISIBLE);
    ValueAnimator va = ValueAnimator.ofInt(0, 300);
    va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        public void onAnimationUpdate(ValueAnimator animation) {
            Integer value = (Integer) animation.getAnimatedValue();
            v.getLayoutParams().height = value.intValue();
            v.invalidate();

        }
    });

    va.start();
}

Peut-être que le problème est de savoir comment je règle la hauteur du LinearLayout? Ou est-ce que je comprends mal la fonction de ValueAnimator? J'ai regardé les articles de blog de Chet Haase, mais ils ne contiennent aucun exemple d'animation de hauteur spécifique. Je n'ai pas non plus été en mesure de trouver et de bons exemples de la façon de travailler avec des animations de hauteur en utilisant les API de la version 3.0+. J'adorerais avoir de l'aide à ce sujet, merci!

23
span

En regardant ce billet de blog: http://tech.chitgoks.com/2011/10/29/Android-animation-to-expand-collapse-view-its-children/ J'ai trouvé que je ne devrais pas n'utilisez pas view.invalidate() pour redessiner la disposition. Je devrais utiliser view.requestLayout().

Ainsi, le code devient quelque chose comme ceci:

ValueAnimator va = ValueAnimator.ofInt(0, height);
    va.setDuration(700);
    va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        public void onAnimationUpdate(ValueAnimator animation) {
            Integer value = (Integer) animation.getAnimatedValue();
            v.getLayoutParams().height = value.intValue();
            v.requestLayout();
        }
    });

Je voulais juste ajouter une note sur la façon d'obtenir la hauteur du LinearLayout ainsi que pour rendre l'animation dynamique. Pour obtenir la hauteur, toutes les vues doivent être dessinées en premier. Pour cela, nous devons écouter un événement qui nous dit que le dessin est fait. Cela peut être fait à partir de la méthode onResume () comme ceci (notez que dans mon xml j'ai déclaré le conteneur à wrap_content pour la hauteur et il est également visible, car je veux le cacher dès le début, je le fais après l'avoir mesuré):

@Override
    public void onResume() {
        super.onResume();
        final ViewTreeObserver vto = filterContainer.getViewTreeObserver();
        vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                height = filterContainer.getHeight();
                filterContainer.setVisibility(View.GONE);
                filterContainer.getLayoutParams().height = 0;
                filterContainer.requestLayout();
                ViewTreeObserver obs = filterContainer.getViewTreeObserver();
                obs.removeGlobalOnLayoutListener(this);
            }
        });
    }
60
span