繁体   English   中英

如何通过使用 Motion Layout 缩放将 RecyclerView 项目动画化为片段

[英]How to animate RecyclerView item to fragment by scaling with Motion Layout

我正在尝试重新创建与此处示例相同的运动: https : //material.io/develop/android/theming/motion

具体是MaterialContainerTransform下的示例 2

在此处输入图片说明

详细解释提出了一个从RecyclerView转换为ViewPager ,但这不适用于我的Fragment案例。

就目前而言,我无法使这项工作正常进行,而且由于这是一个通用的搜索词,我希望找到的任何可能的示例都在包含RecyclerViewFragment大量通用结果中。

这是我得到的,但只有退出时的Hold动画有效。

对于这个项目,我使用 Java 中的导航架构组件

片段A

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setExitTransition(new Hold());
}

// this is the recycler view item click listener
private ItemClickCallback getClickCallback() {
    return (view) -> {

        FragmentNavigator.Extras extras = new FragmentNavigator.Extras
            .Builder()
            .addSharedElement(view, view.getTransitionName())
            .build();

        NavHostFragment
            .findNavController(this)
            .navigate(R.id.action_navigation, null, null, extras);

    };
}

片段B

@Override
public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setSharedElementEnterTransition(new MaterialContainerTransform());

}

这就对了。 单击已实现或未实现的项目时没有区别,除了由于Hold动画导致的延迟。

这是动画库中的错误还是没有正确完成? 文档没有清楚地显示如何具体地针对这种情况实施这一点,我认为由于缺乏文档,这并没有正确完成。

似乎可用的文档缺少重要的步骤。 在我的例子中,Motion Layout 需要知道如何将单击的项目连接到要设置动画的目标视图。

我不知道当给定来自原始片段和目标片段的 1:1 视图关系时,该步骤是否通常是自动化的,但在这种情况下,它是一个 n:1 视图关系,因此我必须传递view.getTransitionName()捆绑在一起(其他方式使用navargs ),因此它可以告诉如何连接两个视图。

使用问题中的代码,需要做的修改如下:

片段A

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    // if hold is not used then the origin fragment might
    // disappear too soon before the target fragment is
    // fully visible
    setExitTransition(new Hold());

}

@Override
public void onViewCreated(
    @NonNull View view,
    @Nullable Bundle savedInstanceState
) {

    // this is required to animate correctly when the user returns
    // to the origin fragment, gives a chance for the layout
    // to be fully laid out before animating it
    ViewGroup viewGroup = (ViewGroup) view.getParent();
    viewGroup
        .getViewTreeObserver()
        .addOnPreDrawListener(() -> {
            startPostponedEnterTransition();
            return true;
        });

    super.onViewCreated(view, savedInstanceState);

}

// this is the recycler view item click listener
private ItemClickCallback getClickCallback() {
    return (view) -> {

        FragmentNavigator.Extras extras = new FragmentNavigator.Extras
            .Builder()
            .addSharedElement(view, view.getTransitionName())
            .build();

        Bundle bundle = new Bundle();
        bundle.putString("itemTransitionName", view.getTransitionName());

        NavHostFragment
            .findNavController(this)
            .navigate(R.id.action_navigation, bundle, null, extras);

    };
}

片段B

String sharedViewId = "";

@Override
public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    if (getArguments() != null) {
        sharedViewId = getArguments().getString("itemTransitionName");
    }

    setSharedElementEnterTransition(new MaterialContainerTransform());
    postponeEnterTransition();

}

@Override
public void onViewCreated(
    @NonNull View view,
    @Nullable Bundle savedInstanceState
) {

    // binding.getRoot() should be whichever view target you want to animate
    // in the target fragment
    ViewCompat.setTransitionName(binding.getRoot(), sharedViewId);
    super.onViewCreated(view, savedInstanceState);

}

暂无
暂无

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

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