Android: Anzeigen / Ausblenden einer Ansicht mithilfe einer Animation

81

Ich habe hier viele Google-Ergebnisse / -Fragen durchgesehen, um festzustellen, wie eine Ansicht über eine vertikale Animation angezeigt / ausgeblendet werden kann, aber ich kann anscheinend keine finden, die genau richtig oder nicht zu vage ist.

Ich habe ein Layout (Rückgängig-Leiste), das sich unter einem anderen Layout und über mehreren anderen Widgets befindet. Diese Rückgängig-Leiste sollte je nach den Umständen vertikal geöffnet und geschlossen werden.

Momentan setze ich die Ansicht nur so ein, dass sie sichtbar oder verschwunden ist.

Blaskovicz
quelle

Antworten:

64

Legen Sie das Attribut android:animateLayoutChanges="true" im übergeordneten Layout fest.

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

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

Pozuelog
quelle
19

Ich habe eine Erweiterung dafür erstellt RelativeLayout, die Layouts mit Animationen ein- / ausblendet. Es kann jede Art von erweitern View, 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 Originale Animationmit overrideDefaultInAnimationund überschreibenoverrideDefaultOutAnimation

Meine ursprünglichen Animationen waren Ein- / Ausblenden. Ich füge XML-Animationsdateien zum Ein- und Aussetzen auf dem Bildschirm hinzu (Nach oben und von oben übersetzen).

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" />
Rotemmiz
quelle
15

Dies kann vernünftigerweise in einer einzeiligen Anweisung in API 12 und höher erreicht werden. Unten finden Sie ein Beispiel für vdie Ansicht, die Sie animieren möchten.

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

Dadurch wird das Viewbetreffende Objekt um 1000 Pixel nach links verschoben. Um die Ansicht wieder auf die Benutzeroberfläche zu verschieben, gehen Sie einfach wie folgt vor.

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

Ich hoffe, jemand findet das nützlich.

Rudi Kershaw
quelle
11

Wenn Sie nur die Höhe einer Ansicht animieren möchten (von beispielsweise 0 bis zu einer bestimmten Zahl), 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);
Andreas Berheim Brudin
quelle
7

Ich habe diese beiden Funktionen verwendet, um die Ansicht mit Übergangsanimation reibungslos auszublenden und anzuzeigen.

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

            }
        });
    }
Jitendra Ramoliya
quelle
4

Versuchen Sie, die TranslateAnimation- Klasse zu verwenden, die die Animation für Positionsänderungen erstellt. Lesen Sie dies, um Hilfe zu erhalten - 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 Pixel anzeigen möchten. Der Beispielcode wäre -

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

PS: Es gibt viele oder andere Methoden, mit denen Sie die Animation entsprechend Ihren Anforderungen verwenden können. Schauen Sie sich auch RelativeLayout.LayoutParams an, wenn Sie den Code vollständig anpassen möchten. Die Verwendung von TranslateAnimation ist jedoch einfacher.

BEARBEITEN: -Komplexe Version 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 einfügen. Wenn Sie den Namen des Layouts nicht ändern, funktioniert ein anderes Layout möglicherweise nicht. Wenn Sie ihnen einen Animationseffekt verleihen möchten, verringern oder erhöhen Sie die topMargin langsam. Sie können dort auch Thread.sleep () verwenden.

Anfänger
quelle
1
ScaleAnimation ändert die Position nicht, sondern skaliert die Ansicht ... Sie verwechseln TranslateAnimation.
Rotemmiz
Ich denke, Sie haben das, was Sie brauchen, und wenn nicht, hier ist ein Beispielcode - TranslateAnimation anim = new TranslateAnimation (vonX, toX, vonY, toY); view.setAnimation (anim);
Noob
3

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);
        }
    });
SaurabhG
quelle
1

Ermitteln Sie zunächst die Höhe der Ansicht, die Sie sägen möchten, und erstellen Sie einen Booleschen 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 zum Anzeigen des Ausblendens der Ansicht auf 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);


        }

    }
Jachumbelechao nach Mantekilla
quelle
1

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);
}
Ankush Shrivastava
quelle