RecyclerView 项目和 CollapsingToolbar 之间的共享元素动画 activity
Shared element animation between RecyclerView item and CollapsingToolbar within same activity
在我的应用程序中,我有一个通过 RecyclerView
适配器显示的项目列表。如果我单击一个项目,则会在相同的 Activity
中启动一个新的 Fragment
。我的项目布局和我的 Activity 外观(简化)如下:
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>
项目布局:
<RelativeLayout >
<ImageView
android:id="@id/itemImage"
android:transitionName="image" />
<LinearLayout>
<TextView ... />
<TextView ... />
</LinearLayout>
</RelativeLayout>
现在,如果新片段是通过单击项目启动的,我想将项目图像的动画添加到 CollapsingToolbarLayout
中的 ImageView
。我阅读了 the article 有关 ShareElement 动画的内容,但这在这里不起作用,因为这不是真正的 ShareElement 动画。目标 ImageView
不在新片段中,我也不必开始新的 activity(我只使目标 ImageView
在新的 Fragment
中可见)。那么在这种情况下我该如何创建这样的动画呢?
因此,您正在尝试将视图从一种布局动画化到另一种布局。
我认为这可以使用 ViewOverlays API 来实现。您可以看到有关 API .
的详细答案
现在在你的情况下,你最终会得到的是你将 ImageView
添加到根布局的 ViewGroupOverlay
中:
final ViewGroup container = (ViewGroup) findViewById(R.id.content);
container.getOverlay().add(imageView);
...
来自docs:
If the view has a parent, the view will be removed from that parent before being added to the overlay.
因此,一旦您执行 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);
})
Here's 您正在尝试实现的类似功能:
在我的应用程序中,我有一个通过 RecyclerView
适配器显示的项目列表。如果我单击一个项目,则会在相同的 Activity
中启动一个新的 Fragment
。我的项目布局和我的 Activity 外观(简化)如下:
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>
项目布局:
<RelativeLayout >
<ImageView
android:id="@id/itemImage"
android:transitionName="image" />
<LinearLayout>
<TextView ... />
<TextView ... />
</LinearLayout>
</RelativeLayout>
现在,如果新片段是通过单击项目启动的,我想将项目图像的动画添加到 CollapsingToolbarLayout
中的 ImageView
。我阅读了 the article 有关 ShareElement 动画的内容,但这在这里不起作用,因为这不是真正的 ShareElement 动画。目标 ImageView
不在新片段中,我也不必开始新的 activity(我只使目标 ImageView
在新的 Fragment
中可见)。那么在这种情况下我该如何创建这样的动画呢?
因此,您正在尝试将视图从一种布局动画化到另一种布局。
我认为这可以使用 ViewOverlays API 来实现。您可以看到有关 API
现在在你的情况下,你最终会得到的是你将 ImageView
添加到根布局的 ViewGroupOverlay
中:
final ViewGroup container = (ViewGroup) findViewById(R.id.content);
container.getOverlay().add(imageView);
...
来自docs:
If the view has a parent, the view will be removed from that parent before being added to the overlay.
因此,一旦您执行 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);
})
Here's 您正在尝试实现的类似功能: