首页 文章

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

提问于
浏览
76

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

我有一个布局(撤消栏),它位于另一个布局下方和多个其他小部件之上;根据具体情况,此撤销栏应垂直滑动打开并滑动关闭 .

目前,我现在所做的只是将视图设置为可见或消失 .

9 回答

  • 4

    在父布局中设置属性 android:animateLayoutChanges="true" .

    如果视图不是,则将视图放在布局中,并为该布局设置 android:animateLayoutChanges="true" .

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

  • 60

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

    您可以使用 overrideDefaultInAnimationoverrideDefaultOutAnimation 覆盖原始 Animation

    我的原始动画是fadeIn / Out,我正在添加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" />
    
  • 11

    这可以在API 12及更高版本的单行声明中合理地实现 . 下面是一个示例,其中 v 是您要设置动画的视图;

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

    这将使有问题的 View 向左滑动1000px . 要将视图滑回UI,我们可以简单地执行以下操作 .

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

    我希望有人觉得这很有用 .

  • 1

    如果您只想为视图的高度设置动画(从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);
    
  • 15

    我已经使用这两个功能来平滑地隐藏和显示具有过渡动画的视图 .

    @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

    也许你正在寻找的是SlidingDrawer .

  • 5

    尝试使用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更容易使用 .

    EDIT:-Complex version using 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() .

  • 3

    试试这个 .

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

    首先获取想要查看的视图的高度,并在视图显示时设置一个布尔值来保存:

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

相关问题