过渡:过渡完成后如何更改父视图的大小?

时间:2019-07-07 15:19:32

标签: android android-animation android-transitions

在我的应用中,我具有线性的视图布局。这些视图的大小可能会因其自身布局的更改而改变。特别地,第一视图(sceneRoot)由可隐藏部分(view1)和始终可见的部分(view2)组成。我想通过两个步骤来动画view1的出现和消失:

  • 如果view1 消失,则1)view1消失,然后2)view2向上移动(1),
  • 如果view1 出现,则1)view2下移,然后2)view1淡入(2)。

这是到目前为止的结果:

disappear transition appear transition

问题在于sceneRoot一旦更改可见度,就会立即更改其边界。 view1跳至新位置,使消失的过渡看起来更清晰。

理想情况下,我希望view3的高度相应地进行动画处理。如果无法做到这一点,我希望在 之后(而不是在开始过渡之前)更改高度。

这是有问题的布局:

sceneRoot

在此简化示例中,单个<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:id="@+id/scene_root" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:id="@+id/view_1" android:layout_width="match_parent" android:layout_height="200dp" android:background="@android:color/holo_red_light" android:gravity="center" android:text="View 1 (Hideable)" android:textSize="24sp" /> <TextView android:id="@+id/view_2" android:layout_width="match_parent" android:layout_height="100dp" android:background="@android:color/holo_orange_light" android:gravity="center" android:text="View 2" android:textSize="24sp" /> </LinearLayout> <TextView android:id="@+id/view_3" android:layout_width="match_parent" android:layout_height="200dp" android:background="@android:color/holo_green_dark" android:gravity="center" android:text="View 3" android:textSize="24sp" /> </LinearLayout> 就足够了。但是,在现实生活中,布局平坦化并不是那么容易实现。

这是我更改LinearLayout的可见性的方法:

view1

在不求助于拼合扁平化的情况下,我必须解决哪些选项?

谢谢。

2 个答案:

答案 0 :(得分:1)

显然,过渡目标没有场景根的直接子代。

ChangeBounds()添加更多目标可以达到目的:

private fun createTransition(
        isView1Appearing: Boolean
): Transition {
    val view1Fade = Fade().apply {
        addTarget(view1)
        duration = 750
    }

    val changeBounds = ChangeBounds().apply {
        addTarget(sceneRoot)

        addTarget(view2)
        addTarget(view3)

        duration = 750
    }

    return TransitionSet().apply {
        ordering = TransitionSet.ORDERING_SEQUENTIAL

        if (isView1Appearing) {
            addTransition(changeBounds)
            addTransition(view1Fade)
        } else {
            addTransition(view1Fade)
            addTransition(changeBounds)
        }
    }
}

希望对某人有用。

答案 1 :(得分:0)

如果您找到答案,那就太好了。我在这里也添加了一个Answer,尽管它是Java语言,因为我对kotlin不太了解。

 private void toggleView1Visibility() {

        final int originalDimension = sceneRoot.getHeight();
        final int newDimension =sceneRoot.getHeight();


        Boolean isView1Appearing = view1.getVisibility() != View.VISIBLE;

        TransitionManager.beginDelayedTransition(sceneRoot, new TransitionSet()
                .addTransition(new ChangeBounds()));
        if (isView1Appearing){
            ViewGroup.LayoutParams params = sceneRoot.getLayoutParams();
            params.height = newDimension;
            sceneRoot.setLayoutParams(params);
            view1.setVisibility(View.VISIBLE );
        }

        else {
            TransitionManager.beginDelayedTransition(sceneRoot, new TransitionSet()
                    .addTransition(new ChangeBounds()));

            ViewGroup.LayoutParams params = sceneRoot.getLayoutParams();
            params.height = originalDimension;
            sceneRoot.setLayoutParams(params);
            view1.setVisibility(View.GONE);
        }
    }

请记住,sceneroot是布局的父级LL。