wake-up-neo.com

Android: Anzeigen/Ausblenden einer Ansicht mithilfe einer Animation

Ich habe viele Google-Ergebnisse/Fragen hier durchgesehen, um zu bestimmen, wie eine Ansicht über eine vertikale Animation angezeigt/ausgeblendet wird. Ich kann jedoch nicht eine finden, die genau richtig oder nicht zu vage ist.

Ich habe ein Layout (Rückgängigleiste), das unter einem anderen Layout und über mehreren anderen Widgets liegt. Diese Undo-Leiste sollte sich vertikal öffnen und schließen, je nach den Umständen.

Momentan ist alles, was ich jetzt mache, die Ansicht sichtbar zu machen oder zu verschwinden.

76
Blaskovicz

Setzen Sie das Attribut Android:animateLayoutChanges="true" im übergeordneten Layout. 

Fügen Sie die Ansicht in ein Layout ein, falls dies nicht der Fall ist, und legen Sie Android:animateLayoutChanges="true" für dieses Layout fest.

HINWEIS: Dies funktioniert nur ab API Level 11 (Android 3.0).

60
pozuelog

Ich habe eine Erweiterung für RelativeLayout erstellt, die Layouts mit Animationen ein-/ausblenden kann .__ Sie kann jede Art von View erweitern, um diese Funktionen zu erhalten.

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;
    }
}

Sie können die ursprünglichen Animations mit overrideDefaultInAnimation und overrideDefaultOutAnimation überschreiben.

Meine ursprünglichen Animationen waren fadeIn/Out. Ich füge XML-Animationsdateien für das Übersetzen in/aus dem Bildschirm hinzu (Übersetzen nach oben und von oben)

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

Dies kann vernünftigerweise in einer einzeiligen Anweisung in API 12 und höher erreicht werden. Unten ist ein Beispiel, bei dem v die Ansicht ist, die Sie animieren möchten.

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

Dadurch wird die betreffende View um 1000px nach links verschoben. Um die Ansicht wieder auf die Benutzeroberfläche zu verschieben, können Sie einfach Folgendes tun.

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

Ich hoffe jemand findet das nützlich.

15
Rudi Kershaw

Wenn Sie nur die Höhe einer Ansicht animieren möchten (von etwa 0 bis zu einer bestimmten Anzahl), können Sie Ihre eigene Animation implementieren:

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);

Ich habe diese beiden Funktionen verwendet, um die Ansicht mit Übergangsanimation nahtlos auszublenden.

@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

Vielleicht suchen Sie nach einem SlidingDrawer .

5
andrrs

Verwenden Sie TranslateAnimation class, um die Animation für Positionsänderungen zu erstellen. Lesen Sie hier die Hilfe - http://developer.Android.com/reference/Android/view/animation/TranslateAnimation.html

Update: Hier ist das Beispiel dafür. Wenn Sie eine Ansichtshöhe von 50 haben und im Ausblendmodus nur 10 px anzeigen möchten. Der Beispielcode wäre - 

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

PS: Es gibt eine Menge oder andere Methoden, um die Animation je nach Bedarf zu verwenden. Werfen Sie auch einen Blick auf RelativeLayout.LayoutParams, wenn Sie den Code vollständig anpassen möchten. Die Verwendung von TranslateAnimation ist jedoch einfacher zu verwenden.

EDIT: -Komplexversion mit 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);

In diesem Beispielcode wird davon ausgegangen, dass Sie Ihre Ansicht in RelativeLayout setzen. Wenn Sie den Namen des Layouts nicht ändern, funktioniert das andere Layout möglicherweise nicht. Wenn Sie ihnen einen Animationseffekt zuweisen möchten, verringern oder erhöhen Sie den topMargin-Wert langsam. Sie können auch Thread.sleep () verwenden.

4
noob

Versuche dies.

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

Zuerst erhalten Sie die Höhe der Ansicht, die Sie sägen möchten, und erstellen Sie einen Boolean-Wert zum Speichern, wenn die Ansicht angezeigt wird:

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));
            }
        });

Rufen Sie dann die Methode auf, um die Ansicht auszublenden, und ändern Sie den Wert des Booleschen Werts:

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

Die Methode:

/**
     * 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:

In 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>

Funktionen:

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