1

我想在具有两个共享元素的片段之间转换。但问题是:只有一个动画。

共享元素取自第一个片段中列表的 viewHolder。我使用的过渡来自材料库,正是这些https://medium.com/androiddevelopers/material-motion-with-mdc-c1f09bb90bf9

片段 A:

fragmentManager.commit {
            replace([...])
            setReorderingAllowed(true)
            addSharedElement(viewA, viewA.transitionName)
            addSharedElement(viewB, viewB.transitionName)
            addToBackStack(fragmentClass.qualifiedName)
        }

片段 B:

 sharedElementReturnTransition = MaterialContainerTransform().apply {
            scrimColor = Color.TRANSPARENT
            duration = 3000L
            interpolator = DecelerateInterpolator()
        }
 binding.headerContainer.header.cover.transitionName = arguments?.getString("firstTrName") ?: return
 binding.headerContainer.title.cover.transitionName = arguments?.getString("secondTrName") ?: return
 binding.headerContainer.header.setImageResource(arguments?.getString("image") ?: return)
 binding.headerContainer.title.text = arguments?.getString("title") ?: return

似乎只有我在 commit{} 中添加的最后一个元素是转换的元素。我检查了所有内容,转换名称是唯一的,所有数据都在第二个片段中,所有转换名称,这不是参数问题。有任何想法吗?非常感谢您的帮助,这是一个非常重要的客户请求。

4

1 回答 1

1

https://material.io/develop/android/theming/motion

与传统的 Android 共享元素不同,它不是围绕单个共享内容(例如图像)设计的,以便在两个场景之间移动。相反,这里的共享元素是指起始视图或视图组的边界容器(例如列表中项目的整个行布局),将其大小和形状转换为结束视图或视图组的大小和形状(例如,全屏片段)。这些开始和结束容器视图是容器变换的“共享元素”。当这些容器被转换时,它们的内容被交换以创建转换。

两个共享元素无法正常工作。当从列表顶部选择开始视图时,imageView成为一个容器。当从底部选择时,textView成为一个容器。(从下面的 gif 中查看 example1 和 example5 之间的区别)

您可以使用传统的共享元素过渡而不是 Material Motion。


示例和 GIF

fragmentEnd.sharedElementEnterTransition = MaterialContainerTransform().apply {
    scrimColor = Color.TRANSPARENT
    containerColor = Color.TRANSPARENT
    duration = 1000L
    interpolator = DecelerateInterpolator()
}

fragmentEnd.sharedElementReturnTransition = MaterialContainerTransform().apply {
    scrimColor = Color.TRANSPARENT
    containerColor = Color.TRANSPARENT
    duration = 1000L
    isElevationShadowEnabled = false
    interpolator = DecelerateInterpolator()
}

val manager: FragmentManager = activity.supportFragmentManager
manager.beginTransaction()
        .setReorderingAllowed(true)
        .addSharedElement(imageView, imageView.transitionName)
        .addSharedElement(textView, textView.transitionName)
        .addToBackStack(null)
        .replace([...])
        .commit()

在此处输入图像描述


解决方案

您可以像这样更改过渡:

fragmentEnd.sharedElementEnterTransition = getTransition() 
fragmentEnd.sharedElementReturnTransition = getTransition() 

private fun getTransition(): Transition{
    val set = TransitionSet()
    set.ordering = TransitionSet.ORDERING_TOGETHER
    set.addTransition(ChangeBounds())
    set.addTransition(ChangeImageTransform())
    set.addTransition(ChangeTransform())
    return set
}

使用 MaterialContainerTransform 的正确方法:

  • 共享一个元素

      fragmentEnd.sharedElementEnterTransition = MaterialContainerTransform().apply {
          scrimColor = Color.TRANSPARENT
          containerColor = ResourcesCompat.getColor(activity.resources,R.color.purple_amethyst,null)
          duration = 1000L
          startShapeAppearanceModel = ShapeAppearanceModel().withCornerSize(100f)
          interpolator = DecelerateInterpolator()
      }
    
    
     fragmentEnd.sharedElementReturnTransition = MaterialContainerTransform().apply {
          scrimColor = Color.TRANSPARENT
          containerColor = ResourcesCompat.getColor(activity.resources,R.color.purple_amethyst,null)
          duration = 1000L
          endShapeAppearanceModel = ShapeAppearanceModel().withCornerSize(100f)
          interpolator = DecelerateInterpolator()
      }
    
    
      val manager: FragmentManager = activity.supportFragmentManager
      manager.beginTransaction()
              .setReorderingAllowed(true)
              .addSharedElement(imageView, imageView.transitionName)
              .addToBackStack(null)
              .replace([...])
              .commit()
    
  • FragmentEnd 布局:

      <androidx.constraintlayout.widget.ConstraintLayout
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:id="@+id/container"
          android:background="@color/purple_amethyst">
    
         <....../>
    
      </androidx.constraintlayout.widget.ConstraintLayout>
    
  • 将过渡名称设置为 fragmentEnd 的顶部布局

    ViewCompat.setTransitionName(binding.container, getArguments().getString("imageViewTransitionName"));
    

结果

在此处输入图像描述

于 2021-05-02T14:37:33.967 回答