简体   繁体   English

Android:LinearLayout滑出屏幕动画

[英]Android: LinearLayout slide off screen animation

I have two layouts (green on top, red on bottom) in a vertical LinearLayout (parent) looking similar to this: 我在垂直LinearLayout(父级)中有两个布局(顶部为绿色,底部为红色),类似于以下所示:

.

When focus goes from the green to red, I would like the green to slide up off the screen and have the red simultaneously slide up with it and fill the whole screen. 当焦点从绿色变为红色时,我希望绿色从屏幕上滑落,让红色同时向上滑动并填满整个屏幕。 And when focus moves from red back up I want the green to slide back into the screen and return to the original configuration. 当焦点从红色向后移动时,我希望绿色滑回屏幕并返回原始配置。 I have tried looking at many other questions but none have had the solution I need. 我尝试查看许多其他问题,但是没有一个问题有我需要的解决方案。 I tried just changing visibility between gone and visible but I want it to be a smooth animation. 我尝试只是在消失和可见之间更改可见性,但我希望它是一个平滑的动画。 I've tried using parentLayout.animate().translationY(greenLayout.getHeight()) on the outer LinearLayout and that does give the animation I want but then the red does not expand to fill the screen, like this: 我试过在外部LinearLayout上使用parentLayout.animate().translationY(greenLayout.getHeight()) ,它确实提供了我想要的动画,但是红色却无法展开以填充屏幕,如下所示:

.

I know this question is similar to this one but that question is really old and only had one answer which didn't work for me. 我知道这个问题与类似,但是这个问题确实很老,只有一个答案对我不起作用。

My solution has a lot of different pieces, so I'll start with the full XML and java code, and then talk about the important bits: 我的解决方案有很多不同的部分,因此,我将从完整的XML和Java代码开始,然后讨论重要的内容:

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical"> <View android:id="@+id/green" android:layout_width="match_parent" android:layout_height="100dp" android:background="#0f0" /> <View android:id="@+id/red" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:background="#f00"/> </LinearLayout> 

In the XML, the only really important part is that the red view uses a height of 0dp and weight of 1 . 在XML中,唯一真正重要的部分是红色视图使用0dp的高度和1权重。 This means it takes up all extra vertical space, which will be important when we get rid of the green view. 这意味着它将占用所有额外的垂直空间,这在我们摆脱绿色视野时将非常重要。

 public class MainActivity extends AppCompatActivity { private int originalHeight; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final View green = findViewById(R.id.green); final View red = findViewById(R.id.red); green.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { green.getViewTreeObserver().removeGlobalOnLayoutListener(this); originalHeight = green.getHeight(); } }); green.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { animateHeightOfView(green, originalHeight, 0); } }); red.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { animateHeightOfView(green, 0, originalHeight); } }); } private void animateHeightOfView(final View view, int start, int end) { ValueAnimator animator = ValueAnimator.ofInt(start, end); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { int height = (int) valueAnimator.getAnimatedValue(); ViewGroup.LayoutParams params = view.getLayoutParams(); params.height = height; view.setLayoutParams(params); } }); animator.start(); } } 

In the Java, the two main parts are the ViewTreeObserver.OnGlobalLayoutListener and the animateHeightOfView() method. 在Java中,两个主要部分是ViewTreeObserver.OnGlobalLayoutListeneranimateHeightOfView()方法。

The OnGlobalLayoutListener exists to capture the green view's original height. 存在OnGlobalLayoutListener来捕获绿色视图的原始高度。 We have to use a listener to do this instead of just writing originalHeight = green.getHeight() inside onCreate() because the green view isn't actually laid out at that point, so getHeight() would return 0 if we tried that. 我们必须使用侦听器来执行此操作,而不是只在onCreate() originalHeight = green.getHeight()内编写originalHeight = green.getHeight()因为此时实际上并未布置绿色视图,因此如果尝试这样做, getHeight()将返回0

The animateHeightOfView() method leverages the ValueAnimator class to animate the height of whatever view you pass to it. animateHeightOfView()方法利用ValueAnimator类对传递给它的任何视图的高度进行动画处理。 Since there's no direct setter for a view's height, we can't use simpler methods like .animate() . 由于没有直接设置视图高度的设置器,因此我们不能使用.animate()类的简单方法。 We set up the ValueAnimator to produce int values on every frame, and then we use a ValueAnimator.AnimatorUpdateListener to modify the view's LayoutParams to set the height. 我们将ValueAnimator设置为在每帧上生成int值,然后使用ValueAnimator.AnimatorUpdateListener修改视图的LayoutParams来设置高度。

Feel free to play with it. 随意玩。 I'm using click listeners to trigger the animation, and you mentioned focus, but you should be able to call animateHeightOfView() in a different way if it suits you. 我使用点击侦听器触发动画,您提到了焦点,但是如果适合的话,您应该能够以其他方式调用animateHeightOfView()

在此处输入图片说明 在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM