使用上/下滑动animation显示和隐藏视图
我有一个LinearLayout
,我想显示或隐藏一个Animation
,只要我改变它的可见性,向上或向下推动布局。
我看过几个样本,但没有一个适合我的需求。
我为animation创build了两个xml文件,但是当我更改LinearLayout
的可见性时,我不知道如何启动它们。
使用Android 3.0(Honeycomb)中引入的新animationAPI,创build这样的animation非常简单。
向下滑动View
:
view.animate().translationY(distance);
您可以稍后将View
滑回原始位置,如下所示:
view.animate().translationY(0);
您还可以轻松地组合多个animation。 下面的animation会将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
所以我们可以在animation完成后将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); } });
当LinearLayout
的可见性通过创buildLinearLayout
的新子类并重写setVisibility()
来启动Animation
时,您可以开始正确的Animations
。 考虑这样的事情:
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); } }
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); } }); }
最简单的解决scheme:在持有视图的容器上设置android:animateLayoutChanges="true"
。
把它放到一个上下文中:如果你有一个如下的布局,那么这个容器中的视图的所有可见性改变都会自动生成animation。
<LinearLayout android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" android:animateLayoutChanges="true" > <Views_which_change_visibility> </LinearLayout>
你可以find更多关于这个animation布局变化的详细信息- Android开发人员
我正在理解应用已被接受的答案。 我需要更多的背景。 现在我已经知道了,这里是一个完整的例子:
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>
笔记
- 感谢这篇文章指出我正确的方向。 这比在这个页面上的其他答案更有帮助。
- 如果您想从屏幕上的视图开始,那么不要将其初始化为
INVISIBLE
。 - 由于我们在屏幕上完全制作animation,因此不需要将其设置为
INVISIBLE
。 如果您不是完全脱离屏幕的animation,那么您可以添加一个alphaanimation并使用AnimatorListenerAdapter
设置可见性。 - 属性animation文档
您可以使用android应用程序中的波纹pipe代码上下滑动任何视图或布局
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)); }
这是我的解决scheme。 只需获得对您的观点的参考并调用此方法:
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(); } }); }
无需做任何事情=)
使用这个类:
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; } }
我有一个angular落的情况下,我的观点的高度仍然是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); } }); } }