在同一活动中RecyclerView项和CollapsingToolbar之间的共享元素动画

Cil*_*nco 9 animation android android-animation android-layout android-view

在我的应用程序中,我有一个通过RecyclerView适配器显示的项目列表.如果我点击一个项目Fragment,则在同一个项目中启动Activity.我的项目的布局和我的活动看起来(简化)像这样:

活动布局:

<android.support.design.widget.CoordinatorLayout>

    <android.support.design.widget.AppBarLayout>

        <android.support.design.widget.CollapsingToolbarLayout>

            <ImageView
                android:id="@+id/image"
                android:transitionName="image" ... />

            <android.support.v7.widget.Toolbar ... />

        </android.support.design.widget.CollapsingToolbarLayout>

        <android.support.design.widget.TabLayout ... />

    </android.support.design.widget.AppBarLayout>

    <FrameLayout... />

</android.support.design.widget.CoordinatorLayout>
Run Code Online (Sandbox Code Playgroud)

物品布局:

<RelativeLayout >

    <ImageView
        android:id="@id/itemImage"
        android:transitionName="image" />

    <LinearLayout>

        <TextView ... />

        <TextView ... />

    </LinearLayout>

</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)

现在,如果新片段通过项目点击开始,我想的物品图像的动画添加到ImageViewCollapsingToolbarLayout.我阅读有关ShareElement动画的文章,但这不适用于此,因为这不是真正的ShareElement动画.目标ImageView不在新片段中,我也不必开始新活动(我只ImageView在新的目标中显示目标Fragment).那么在这种情况下如何创建这样的动画呢?

azi*_*ian 7

因此,您尝试将视图从一个布局设置为另一个布局.

我认为这可以使用ViewOverlays API实现.您可以在此处查看有关该API的详细答案.

现在,在您的情况下,您最终将添加ImageViewViewGroupOverlay根布局:


    final ViewGroup container = (ViewGroup) findViewById(R.id.content);
    container.getOverlay().add(imageView);
    ...

来自文档:

如果视图具有父级,则视图将在添加到叠加层之前从该父级中删除.

因此,只要您执行getOverlay().add(imageView)视图,就会从其父级中删除.现在您可以自由创建动画并移动imageView到最终目的地.


    final ViewGroup container = (ViewGroup) findViewById(R.id.content);
    container.getOverlay().add(imageView);

    // animate imageView by any API, e.g. ViewPropertyHolder
    imageView.animate()
             .x(finalX)
             .y(finalY)
             .setDuration(duration)
             .setInterpolator(interpolator)
             .withEndAction(() -> {
                // crucial point, remove the overlay
                container.getOverlay().remove(imageView);

                // add this `imageView` to the destination layout
                destLayout.addView(imageView);
             })

这是您尝试实现的类似功能:

在此输入图像描述