Android:使用动画显示/隐藏视图


81

我一直在这里查看许多Google搜索结果/问题,以确定如何通过垂直动画显示/隐藏视图,但是我似乎找不到一个完全正确或不太模糊的视图。

我有一个布局(撤消栏),该布局在另一个布局之下,在多个其他小部件之上;撤消栏应根据情况垂直滑动打开和关闭。

目前,我现在所做的所有操作都是将视图设置为可见或消失。

Answers:


64

android:animateLayoutChanges="true" 在父布局内设置属性 。

如果没有放置视图,则将其放置在该布局中并android:animateLayoutChanges="true"为该布局设置。

注意:仅适用于API Level 11+(Android 3.0)


19

我为此创建了一个扩展,用于RelativeLayout显示/隐藏带有动画的布局。它可以扩展任何种类View以获得这些功能。

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

您可以Animation使用overrideDefaultInAnimation和覆盖原始。overrideDefaultOutAnimation

我原来的动画是淡入/淡出,我正在添加XML动画文件以在屏幕上进行移入/移出(移至顶部和顶部)

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" />

15

可以在API 12及更高版本中的单行语句中合理地实现这一点。下面是一个v您希望为其设置动画的视图的示例;

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

这会将相关View问题向左滑动1000像素。要将视图滑动回UI,我们可以简单地执行以下操作。

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

我希望有人觉得这有用。


11

如果只想对视图的高度进行动画处理(从0到一定数量),则可以实现自己的动画:

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

7

我使用了这两个功能来平滑地隐藏和显示带有过渡动画的视图。

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

            }
        });
    }

4

尝试使用TranslateAnimation类,该类创建用于位置更改的动画。尝试阅读以下内容以获取帮助-http://developer.android.com/reference/android/view/animation/TranslateAnimation.html

更新:这是此示例。如果您的视图高度为50,并且在隐藏模式下只希望显示10像素。示例代码将是-

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

PS:有很多方法可以帮助您根据需要使用动画。如果要完全自定义代码,也可以查看RelativeLayout.LayoutParams,但是使用TranslateAnimation更容易使用。

编辑:使用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);

此示例代码假定您将视图放在RelativeLayout中,如果不更改Layout的名称,则其他布局可能无法正常工作。如果要对其赋予动画效果,请缓慢减小或增大topMargin。您也可以考虑在那里使用Thread.sleep()。


1
ScaleAnimation不会改变位置,它会缩放视图...您对TranslateAnimation感到困惑。
Rotemmiz 2012年

我想您已经满足了您的需求,如果没有,这里是示例代码-TranslateAnimation anim = new TranslateAnimation(fromX,toX,fromY,toY); view.setAnimation(anim);
noob 2012年

3

试试这个。

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

1

首先获取要查看的视图的高度,并在显示视图时进行布尔值保存:

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

然后调用用于显示隐藏视图的方法,并更改布尔值:

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

方法:

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


        }

    }

1

ViewAnimator:

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

职能:

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);
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.