web-dev-qa-db-fra.com

Android: afficher/masquer une vue à l'aide d'une animation

J'ai parcouru de nombreux résultats/questions sur Google ici pour déterminer comment afficher/masquer une vue via une animation verticale, mais je n'arrive pas à en trouver une qui soit exacte ou qui ne soit pas trop vague.

J'ai une mise en page (barre d'annulation) qui se trouve en dessous d'une autre et au-dessus de plusieurs autres widgets; cette barre d'annulation doit glisser verticalement et s'ouvrir, en fonction des circonstances.

Actuellement, tout ce que je fais maintenant, c’est que la vue soit visible ou disparaisse.

76
Blaskovicz

Définir l'attribut Android:animateLayoutChanges="true" à l'intérieur de la mise en page parent. 

Mettez la vue dans une présentation si ce n'est pas le cas et définissez Android:animateLayoutChanges="true" pour cette présentation.

REMARQUE: cela ne fonctionne qu'à partir de l'API niveau 11+ (Android 3.0).

60
pozuelog

J'ai créé une extension pour RelativeLayout qui affiche/masque les dispositions avec animations . Elle peut étendre tout type de View pour obtenir ces fonctionnalités.

import Android.content.Context;
import Android.util.AttributeSet;
import Android.view.View;
import Android.view.animation.Animation;
import Android.view.animation.AnimationSet;
import Android.view.animation.AnimationUtils;
import Android.widget.RelativeLayout;

public class AnimatingRelativeLayout extends RelativeLayout
{
    Context context;
    Animation inAnimation;
    Animation outAnimation;

    public AnimatingRelativeLayout(Context context)
    {
        super(context);
        this.context = context;
        initAnimations();

    }

    public AnimatingRelativeLayout(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        this.context = context;
        initAnimations();
    }

    public AnimatingRelativeLayout(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
        this.context = context;
        initAnimations();
    }

    private void initAnimations()
    {
        inAnimation = (AnimationSet) AnimationUtils.loadAnimation(context, R.anim.in_animation);
        outAnimation = (Animation) AnimationUtils.loadAnimation(context, R.anim.out_animation);
    }

    public void show()
    {
        if (isVisible()) return;
        show(true);
    }

    public void show(boolean withAnimation)
    {
        if (withAnimation) this.startAnimation(inAnimation);
        this.setVisibility(View.VISIBLE);
    }

    public void hide()
    {
        if (!isVisible()) return;
        hide(true);
    }

    public void hide(boolean withAnimation)
    {
        if (withAnimation) this.startAnimation(outAnimation);
        this.setVisibility(View.GONE);
    }

    public boolean isVisible()
    {
        return (this.getVisibility() == View.VISIBLE);
    }

    public void overrideDefaultInAnimation(Animation inAnimation)
    {
        this.inAnimation = inAnimation;
    }

    public void overrideDefaultOutAnimation(Animation outAnimation)
    {
        this.outAnimation = outAnimation;
    }
}

Vous pouvez remplacer la Animations originale en utilisant overrideDefaultInAnimation et overrideDefaultOutAnimation

Mes animations originales étaient fadeIn/Out, j'ajoute des fichiers d'animation XML pour la traduction dans/hors de l'écran (Traduire en haut et en haut)

in_animation.xml:

    <?xml version="1.0" encoding="utf-8"?>
<translate xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:duration="600"
    Android:fillAfter="false"
    Android:fromXDelta="0"
    Android:fromYDelta="-100%p"
    Android:toXDelta="0"
    Android:toYDelta="0" />

out_animation.xml: 

  <?xml version="1.0" encoding="utf-8"?>
<translate xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:duration="600"
    Android:fillAfter="false"
    Android:fromXDelta="0"
    Android:fromYDelta="0"
    Android:toXDelta="0"
    Android:toYDelta="-100%p" />
19
Rotemmiz

Cela peut raisonnablement être réalisé dans une déclaration de ligne unique dans API 12 et versions ultérieures. Voici un exemple où v est la vue que vous souhaitez animer;

v.animate().translationXBy(-1000).start();

Cela fera glisser la View en question vers la gauche de 1000 pixels. Pour remettre la vue sur l'interface utilisateur, nous pouvons simplement procéder comme suit.

v.animate().translationXBy(1000).start();

J'espère que quelqu'un trouvera cela utile.

15
Rudi Kershaw

Si vous souhaitez uniquement animer la hauteur d'une vue (de 0 à un certain nombre), vous pouvez implémenter votre propre animation:

final View v = getTheViewToAnimateHere();
Animation anim=new Animation(){
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        super.applyTransformation(interpolatedTime, t);
        // Do relevant calculations here using the interpolatedTime that runs from 0 to 1
        v.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, (int)(30*interpolatedTime)));
    }};
anim.setDuration(500);
v.startAnimation(anim);
11

J'ai utilisé ces deux fonctions pour masquer et afficher la vue avec animation de transition en douceur.

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public void expand(final View v, int duration, int targetHeight, final int position) {

        int prevHeight = v.getHeight();

        v.setVisibility(View.VISIBLE);
        ValueAnimator valueAnimator = ValueAnimator.ofInt(0, targetHeight);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                v.getLayoutParams().height = (int) animation.getAnimatedValue();
                v.requestLayout();
            }
        });
        valueAnimator.setInterpolator(new DecelerateInterpolator());
        valueAnimator.setDuration(duration);
        valueAnimator.start();
        valueAnimator.addListener(new AnimatorListenerAdapter() {

            @Override
            public void onAnimationEnd(Animator animation) {
                v.clearAnimation();
            }
        });

    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public void collapse(final View v, int duration, int targetHeight, final int position) {
        if (position == (data.size() - 1)) {
            return;
        }
        int prevHeight = v.getHeight();
        ValueAnimator valueAnimator = ValueAnimator.ofInt(prevHeight, targetHeight);
        valueAnimator.setInterpolator(new DecelerateInterpolator());
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                v.getLayoutParams().height = (int) animation.getAnimatedValue();
                v.requestLayout();
            }
        });
        valueAnimator.setInterpolator(new DecelerateInterpolator());
        valueAnimator.setDuration(duration);
        valueAnimator.start();
        valueAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                animBoolArray.put(position, false);
                v.clearAnimation();

            }
        });
    }
7

Peut-être que ce que vous recherchez est un SlidingDrawer .

5
andrrs

Essayez d'utiliser TranslateAnimation class, qui crée l'animation pour les changements de position. Essayez de lire ceci pour vous aider - http://developer.Android.com/reference/Android/view/animation/TranslateAnimation.html

Mise à jour: Voici l'exemple pour cela. Si vous avez la hauteur de votre vue égale à 50 et qu'en mode masqué, vous ne souhaitez afficher que 10 px. L'exemple de code serait - 

TranslateAnimation anim=new TranslateAnimation(0,0,-40,0);
anim.setFillAfter(true);
view.setAnimation(anim);

PS: Il existe de nombreuses méthodes pour vous aider à utiliser l'animation selon vos besoins. Jetez également un coup d'oeil à RelativeLayout.LayoutParams si vous souhaitez personnaliser complètement le code, mais l'utilisation de TranslateAnimation est plus facile à utiliser.

EDIT: - Version complexe utilisant LayoutParams

RelativeLayout relParam=new RelativeLayout.LayoutParam(RelativeLayout.LayoutParam.FILL_PARENT,RelativeLayout.LayoutParam.WRAP_CONTENT); //you can give hard coded width and height here in (width,height) format.
relParam.topMargin=-50; //any number that work.Set it to 0, when you want to show it.
view.setLayoutParams(relparam);

Cet exemple de code suppose que vous mettez votre vue dans RelativeLayout. Si vous ne modifiez pas le nom de Layout, une autre disposition risque de ne pas fonctionner. Si vous souhaitez leur donner un effet d'animation, réduisez ou augmentez lentement la marge supérieure. Vous pouvez également utiliser Thread.sleep ().

4
noob

Essaye ça.

view.animate()
    .translationY(0)
    .alpha(0.0f)
    .setListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {
            super.onAnimationEnd(animation);
            view.setVisibility(View.GONE);
        }
    });
3
SaurabhG

Tout d’abord, obtenez la hauteur de la vue que vous souhaitez voir et créez un booléen à enregistrer si la vue est affichée:

int heigth=0;
boolean showing=false;
LinearLayout layout = (LinearLayout) view.findViewById(R.id.layout);

        proDetailsLL.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

            @Override
            public void onGlobalLayout() {
                // gets called after layout has been done but before display
                // so we can get the height then hide the view

                proHeight = proDetailsLL.getHeight(); // Ahaha!  Gotcha

                proDetailsLL.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                proDetailsLL.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, 0));
            }
        });

Appelez ensuite la méthode pour afficher masquer la vue et modifiez la valeur du booléen:

slideInOutAnimation(showing, heigth, layout);
proShowing = !proShowing;

La méthode:

/**
     * Method to slide in out the layout
     * 
     * @param isShowing
     *            if the layout is showing
     * @param height
     *            the height to slide
     * @param slideLL
     *            the container to show
     */
private void slideInOutAnimation(boolean isShowing, int height, final LinearLayout slideLL, final ImageView arroIV) {

        if (!isShowing) {
        Animation animIn = new Animation() {
        protected void applyTransformation(float interpolatedTime, Transformation t) {
                    super.applyTransformation(interpolatedTime, t);
        // Do relevant calculations here using the interpolatedTime that runs from 0 to 1
        slideLL.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, (int) (heigth * interpolatedTime)));

                }
            };
            animIn.setDuration(500);
            slideLL.startAnimation(animIn);
        } else {

            Animation animOut = new Animation() {
                protected void applyTransformation(float interpolatedTime, Transformation t) {
                    super.applyTransformation(interpolatedTime, t);
                    // Do relevant calculations here using the interpolatedTime that runs from 0 to 1


                        slideLL.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,
                                (int) (heigth * (1 - interpolatedTime))));

                }
            };
            animOut.setDuration(500);
            slideLL.startAnimation(animOut);


        }

    }

ViewAnimator:

En XML:

  <ViewAnimator
    Android:id="@+id/animator_message"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:inAnimation="@anim/slide_down_text"
    Android:outAnimation="@anim/slide_up_text">

    <TextView
        Android:id="@+id/text_message_authentication"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:gravity="center_horizontal"
        Android:text="message_error_authentication" />

    <TextView
        Android:id="@+id/text_message_authentication_connection"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:gravity="center_horizontal"
        Android:text="message_error_authentication_connection" />

    <TextView
        Android:id="@+id/text_message_authentication_empty"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:gravity="center_horizontal"
        Android:text="message_error_authentication_field_empty" />

</ViewAnimator>

Les fonctions:

public void show(int viewId) {
    ViewAnimator animator = (ViewAnimator) findView(animatorId);
    View view = findViewById(viewId);

    if (animator.getDisplayedChild() != animator.indexOfChild(view)) {
        animator.setDisplayedChild(animator.indexOfChild(view));
     }
 }


 private void showAuthenticationConnectionFailureMessage() {
    show(R.id.text_message_authentication_connection);
}
0
Ankush Shrivastava