首页 文章

使用向上/向下滑动动画显示和隐藏视图

提问于
浏览
241

我有一个 LinearLayout ,我希望用_412108显示或隐藏,只要我改变其可见性,就会向上或向下推动布局 .

我在那里看到了一些样品,但它们都不适合我的需要 .

我为动画创建了两个xml文件,但是当我更改 LinearLayout 的可见性时,我不知道如何启动它们 .

10 回答

  • 13

    Kotlin

    基于Suragchanswer,这是一种使用View扩展的优雅方式:

    fun View.slideUp(duration: Int = 500) {
        visibility = View.VISIBLE
        val animate = TranslateAnimation(0f, 0f, this.height.toFloat(), 0f)
        animate.duration = duration.toLong()
        animate.fillAfter = true
        this.startAnimation(animate)
    }
    
    fun View.slideDown(duration: Int = 500) {
        visibility = View.VISIBLE
        val animate = TranslateAnimation(0f, 0f, 0f, this.height.toFloat())
        animate.duration = duration.toLong()
        animate.fillAfter = true
        this.startAnimation(animate)
    }
    

    然后无论你想在哪里使用它,你只需要 myView.slideUp()myView.slideDown()

  • 4

    最简单的解决方案:在容纳视图的容器上设置 android:animateLayoutChanges="true" .

    将其置于某些上下文中:如果您具有如下所示的布局,则将自动为此容器中的视图的所有可见性更改进行动画处理 .

    <LinearLayout android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:animateLayoutChanges="true"
        >
    
        <Views_which_change_visibility>
    
    </LinearLayout>
    

    你可以在Animating Layout Changes - Android Developer找到更多相关细节

  • 1

    我在理解应用已接受的答案时遇到了麻烦 . 我需要更多的背景 . 现在我已经弄明白了,这是一个完整的例子:

    enter image description here

    MainActivity.java

    public class MainActivity extends AppCompatActivity {
    
        Button myButton;
        View myView;
        boolean isUp;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            myView = findViewById(R.id.my_view);
            myButton = findViewById(R.id.my_button);
    
            // initialize as invisible (could also do in xml)
            myView.setVisibility(View.INVISIBLE);
            myButton.setText("Slide up");
            isUp = false;
        }
    
        // slide the view from below itself to the current position
        public void slideUp(View view){
            view.setVisibility(View.VISIBLE);
            TranslateAnimation animate = new TranslateAnimation(
                    0,                 // fromXDelta
                    0,                 // toXDelta
                    view.getHeight(),  // fromYDelta
                    0);                // toYDelta
            animate.setDuration(500);
            animate.setFillAfter(true);
            view.startAnimation(animate);
        }
    
        // slide the view from its current position to below itself
        public void slideDown(View view){
            TranslateAnimation animate = new TranslateAnimation(
                    0,                 // fromXDelta
                    0,                 // toXDelta
                    0,                 // fromYDelta
                    view.getHeight()); // toYDelta
            animate.setDuration(500);
            animate.setFillAfter(true);
            view.startAnimation(animate);
        }
    
        public void onSlideViewButtonClick(View view) {
            if (isUp) {
                slideDown(myView);
                myButton.setText("Slide up");
            } else {
                slideUp(myView);
                myButton.setText("Slide down");
            }
            isUp = !isUp;
        }
    }
    

    activity_mail.xml

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.example.slideview.MainActivity">
    
        <Button
            android:id="@+id/my_button"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="100dp"
            android:onClick="onSlideViewButtonClick"
            android:layout_width="150dp"
            android:layout_height="wrap_content"/>
    
        <LinearLayout
            android:id="@+id/my_view"
            android:background="#a6e1aa"
            android:orientation="vertical"
            android:layout_alignParentBottom="true"
            android:layout_width="match_parent"
            android:layout_height="200dp">
    
        </LinearLayout>
    
    </RelativeLayout>
    

    注意事项

    • 感谢this article指出我正确的方向 . 它比这个页面上的其他答案更有帮助 .

    • 如果要从屏幕上的视图开始,则不要将其初始化为 INVISIBLE .

    • 由于我们在屏幕上完全动画,因此无需将其设置回 INVISIBLE . 但是,如果您没有完全关闭屏幕动画,则可以添加Alpha动画并使用 AnimatorListenerAdapter 设置可见性 .

    • Property Animation docs

  • 3
    if (filter_section.getVisibility() == View.GONE) {
        filter_section.animate()
                .translationY(filter_section.getHeight()).alpha(1.0f)
                .setListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationStart(Animator animation) {
                        super.onAnimationStart(animation);
                        filter_section.setVisibility(View.VISIBLE);
                        filter_section.setAlpha(0.0f);
                    }
                });
    } else {
        filter_section.animate()
                .translationY(0).alpha(0.0f)
                .setListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        super.onAnimationEnd(animation);
                        filter_section.setVisibility(View.GONE);
                    }
                });
    }
    
  • 11

    LinearLayout 的可见性发生变化时,您可以通过创建 LinearLayout 的新子类并重写 setVisibility() 以启动 Animations 来启动正确的 Animation . 考虑这样的事情:

    public class SimpleViewAnimator extends LinearLayout
    {
        private Animation inAnimation;
        private Animation outAnimation;
    
        public SimpleViewAnimator(Context context)
        {
            super(context);
        }
    
        public void setInAnimation(Animation inAnimation)
        {
            this.inAnimation = inAnimation;
        }
    
        public void setOutAnimation(Animation outAnimation)
        {
            this.outAnimation = outAnimation;
        }
    
        @Override
        public void setVisibility(int visibility)
        {
            if (getVisibility() != visibility)
            {
                if (visibility == VISIBLE)
                {
                    if (inAnimation != null) startAnimation(inAnimation);
                }
                else if ((visibility == INVISIBLE) || (visibility == GONE))
                {
                    if (outAnimation != null) startAnimation(outAnimation);
                }
            }
    
            super.setVisibility(visibility);
        }
    }
    
  • 10

    使用这个类:

    public class ExpandCollapseExtention {
    
     public static void expand(View view) {
        view.setVisibility(View.VISIBLE);
    
        final int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
        final int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
        view.measure(widthSpec, heightSpec);
    
        ValueAnimator mAnimator = slideAnimator(view, 0, view.getMeasuredHeight());
        mAnimator.start();
    }
    
    
    public static void collapse(final View view) {
        int finalHeight = view.getHeight();
    
        ValueAnimator mAnimator = slideAnimator(view, finalHeight, 0);
    
        mAnimator.addListener(new Animator.AnimatorListener() {
    
            @Override
            public void onAnimationEnd(Animator animator) {               
                view.setVisibility(View.GONE);
            }
    
    
            @Override
            public void onAnimationStart(Animator animation) {
    
            }
    
    
            @Override
            public void onAnimationCancel(Animator animation) {
    
            }
    
    
            @Override
            public void onAnimationRepeat(Animator animation) {
    
            }
        });
        mAnimator.start();
    }
    
    
    private static ValueAnimator slideAnimator(final View v, int start, int end) {
    
        ValueAnimator animator = ValueAnimator.ofInt(start, end);
    
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
    
                int value = (Integer) valueAnimator.getAnimatedValue();
                ViewGroup.LayoutParams layoutParams = v.getLayoutParams();
                layoutParams.height = value;
                v.setLayoutParams(layoutParams);
            }
        });
        return animator;
    }
    }
    
  • 60

    使用Android 3.0(Honeycomb)中引入的新动画API,创建此类动画非常简单 .

    View 向下滑动一段距离:

    view.animate().translationY(distance);
    

    您可以稍后将 View 滑回原来的位置,如下所示:

    view.animate().translationY(0);
    

    您还可以轻松组合多个动画 . 以下动画将向下滑动 View 高度并同时淡入其中:

    // Prepare the View for the animation
    view.setVisibility(View.VISIBLE);
    view.setAlpha(0.0f);
    
    // Start the animation
    view.animate()
        .translationY(view.getHeight())
        .alpha(1.0f)
        .setListener(null);
    

    然后,您可以将 View 淡出并将其滑回原始位置 . 我们还设置了 AnimatorListener ,因此我们可以在动画结束后将 View 的可见性设置回 GONE

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

    您可以使用Android应用程序中的波纹管代码上下滑动任何视图或布局

    boolean isClicked=false;
    LinearLayout mLayoutTab = (LinearLayout)findViewById(R.id.linearlayout);
    
            if(isClicked){
                        isClicked = false;
                        mLayoutTab.animate()
                        .translationYBy(120)
                        .translationY(0)     
                        .setDuration(getResources().getInteger(android.R.integer.config_mediumAnimTime));
    
            }else{
                    isClicked = true;
                    mLayoutTab.animate()
                    .translationYBy(0)
                    .translationY(120)
                    .setDuration(getResources().getInteger(android.R.integer.config_mediumAnimTime));
                    }
    
  • 2

    我有一个角落的情况,我的视图的高度仍然是 zero 所以......

    import android.animation.Animator;
    import android.animation.AnimatorListenerAdapter;
    import android.view.View;
    
    public final class AnimationUtils {
    
      public static void slideDown(final View view) {
            view.animate()
                    .translationY(view.getHeight())
                    .alpha(0.f)
                    .setListener(new AnimatorListenerAdapter() {
                        @Override
                        public void onAnimationEnd(Animator animation) {
                            // superfluous restoration
                            view.setVisibility(View.GONE);
                            view.setAlpha(1.f);
                            view.setTranslationY(0.f);
                        }
                    });
        }
    
        public static void slideUp(final View view) {
            view.setVisibility(View.VISIBLE);
            view.setAlpha(0.f);
    
            if (view.getHeight() > 0) {
                slideUpNow(view);
            } else {
                // wait till height is measured
                view.post(new Runnable() {
                    @Override
                    public void run() {
                        slideUpNow(view);
                    }
                });
            }
        }
    
        private static void slideUpNow(final View view) {
            view.setTranslationY(view.getHeight());
            view.animate()
                    .translationY(0)
                    .alpha(1.f)
                    .setListener(new AnimatorListenerAdapter() {
                        @Override
                        public void onAnimationEnd(Animator animation) {
                            view.setVisibility(View.VISIBLE);
                            view.setAlpha(1.f);
                        }
                    });
        }
    
    }
    
  • 541

    这是我的解决方案 . 只需获得对您的视图的引用并调用此方法:

    public static void animateViewFromBottomToTop(final View view){
    
        view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    
            @Override
            public void onGlobalLayout() {
    
                view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
    
                final int TRANSLATION_Y = view.getHeight();
                view.setTranslationY(TRANSLATION_Y);
                view.setVisibility(View.GONE);
                view.animate()
                    .translationYBy(-TRANSLATION_Y)
                    .setDuration(500)
                    .setStartDelay(200)
                    .setListener(new AnimatorListenerAdapter() {
    
                        @Override
                        public void onAnimationStart(final Animator animation) {
    
                            view.setVisibility(View.VISIBLE);
                        }
                    })
                    .start();
            }
        });
    }
    

    无需做任何其他事情=)

相关问题