如何使用Motion Layout缩放动画RecyclerView项以使其片段化

问题描述

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

具体来说,MaterialContainerTransform下的示例2

enter image description here

详细说明提出了一个示例,该示例从RecyclerView过渡到ViewPager,但这不适用于我的Fragment情况。

就目前情况而言,我无法使其正常工作,并且由于这是一个通用搜索词,因此我希望找到的所有可能示例都包含RecyclerViewFragment的通用结果

就我所知,但是只有退出时的Hold动画有效。

对于这个项目,我正在使用Java中的Navigation Architecture组件

片段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,extras);

    };
}

片段B

@Override
public void onCreate(Bundle savedInstanceState) {

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

}

就是这样。单击实现或不实现的项目没有什么区别,除了Hold动画导致的延迟之外。

这是动画库中的错误还是执行不正确?文档没有明确说明如何针对这种情况具体实现这一点,并且我认为由于缺少文档,因此未正确实施。

解决方法

似乎可用的文档缺少重要的步骤。 在我的情况下,“运动布局”需要知道如何将单击的项目连接到要进行动画处理的目标视图。

我不知道从原始片段和目标片段获得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);

}

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...