【问题标题】:Android: LinearLayout slide off screen animationAndroid:LinearLayout滑出屏幕动画
【发布时间】:2017-09-09 12:10:23
【问题描述】:

我在垂直 LinearLayout(父级)中有两个布局(顶部为绿色,底部为红色),看起来类似于:

当焦点从绿色变为红色时,我希望绿色向上滑出屏幕并让红色同时向上滑动并填满整个屏幕。当焦点从红色向上移动时,我希望绿色滑回屏幕并返回原始配置。我已经尝试查看许多其他问题,但没有一个有我需要的解决方案。我尝试在消失和可见之间改变可见性,但我希望它是一个流畅的动画。我已经尝试在外部 LinearLayout 上使用 parentLayout.animate().translationY(greenLayout.getHeight()) 并且确实给出了我想要的动画,但是红色并没有扩展以填充屏幕,如下所示:

.

我知道这个问题类似于this one,但这个问题真的很老,只有一个对我不起作用的答案。

【问题讨论】:

  • 张贴的第二张图片是正在发生的事情还是您想要发生的事情?以及如何让绿色视图在屏幕外显示动画后重新获得焦点?
  • 在第二张图片中,我展示了在绿色消失后,红色不会扩大以填充屏幕,而是保持其原始高度。并通过从红色向上单击返回焦点。

标签: android android-layout animation


【解决方案1】:

我的解决方案有很多不同的部分,所以我将从完整的 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>

在 XML 中,唯一真正重要的部分是红色视图使用 0dp 的高度和 1 的重量。这意味着它会占用所有额外的垂直空间,这在我们摆脱绿色视图时非常重要。

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

在 Java 中,两个主要部分是 ViewTreeObserver.OnGlobalLayoutListeneranimateHeightOfView() 方法。

OnGlobalLayoutListener 的存在是为了捕捉绿色视图的原始高度。我们必须使用侦听器来执行此操作,而不仅仅是在 onCreate() 中写入 originalHeight = green.getHeight(),因为此时实际上并未布置绿色视图,因此如果我们尝试这样做,getHeight() 将返回 0

animateHeightOfView() 方法利用ValueAnimator 类为您传递给它的任何视图的高度设置动画。由于没有直接设置视图高度的方法,我们不能使用像.animate() 这样更简单的方法。我们设置ValueAnimator 以在每一帧上产生int 值,然后我们使用ValueAnimator.AnimatorUpdateListener 修改视图的LayoutParams 来设置高度。

随意玩。我正在使用点击侦听器来触发动画,并且您提到了焦点,但如果适合您,您应该能够以不同的方式调用 animateHeightOfView()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-18
    • 2011-10-19
    • 1970-01-01
    • 2017-03-15
    相关资源
    最近更新 更多