共享元素转换根本不起作用?
Shared element transition not working at all?
这应该是一件很容易实现的事情,但由于某种原因我无法让它工作。我正在使用 SDK 30 模拟器进行测试。基本上新的片段出现了,但是没有任何动画。如果我添加 Fade() 过渡,它仅适用于淡入淡出过渡。我试过设置 sharedElement 回调,但这些方法只是间歇性地调用。基本上它是一个简单的图像。你点击它,新片段出现。再点一下就没了
activity 的布局片段包含图片
<FrameLayout
android:id="@+id/container_test"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
>
<ImageView
android:id="@+id/image_error"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_baseline_error_24"
android:transitionName="image"
android:layout_gravity="center"
/>
</FrameLayout>
打开图像片段的逻辑
override fun openImageFragment(imageView: ImageView) {
val fragment = ImageFragment()
fragment.image = imageView.drawable
fragment.arguments = Bundle().also {
it.putString(ImageFragment.KEY_TRANSITION, imageView.transitionName)
}
// fragment.enterTransition = Fade()
// fragment.exitTransition = Fade()
supportFragmentManager
.beginTransaction()
.setReorderingAllowed(true)
.addSharedElement(imageView, imageView.transitionName)
.replace(R.id.container_test, fragment)
.commitNow()
}
图像片段布局
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black">
<ImageView
android:id="@+id/image_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitCenter"
/>
</FrameLayout>
ImageFragment
class ImageFragment : Fragment() {
private lateinit var binding: FragmentImageBinding
var image: Drawable?= null
companion object {
const val KEY_TRANSITION = "TRANSITION"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val transition = TransitionInflater.from(requireContext()).inflateTransition(android.R.transition.move)
sharedElementEnterTransition = transition
sharedElementReturnTransition = transition
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentImageBinding.inflate(inflater, container, false)
binding.imageView.transitionName = arguments?.getString(KEY_TRANSITION)
binding.imageView.setImageDrawable(image)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
view.setOnClickListener {
requireActivity().supportFragmentManager
.beginTransaction()
.remove(this)
.commit()
}
}
}
经过反复试验,我找到了原因。
我的初始片段静态放置在 XML 上,这阻止了片段管理器替换它。通过使用布局检查器,我发现新片段位于第一个片段的正下方。
基本上,解决方案是以编程方式添加第一个片段,以便片段管理器可以对其进行操作。
这应该是一件很容易实现的事情,但由于某种原因我无法让它工作。我正在使用 SDK 30 模拟器进行测试。基本上新的片段出现了,但是没有任何动画。如果我添加 Fade() 过渡,它仅适用于淡入淡出过渡。我试过设置 sharedElement 回调,但这些方法只是间歇性地调用。基本上它是一个简单的图像。你点击它,新片段出现。再点一下就没了
activity 的布局片段包含图片
<FrameLayout
android:id="@+id/container_test"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
>
<ImageView
android:id="@+id/image_error"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_baseline_error_24"
android:transitionName="image"
android:layout_gravity="center"
/>
</FrameLayout>
打开图像片段的逻辑
override fun openImageFragment(imageView: ImageView) {
val fragment = ImageFragment()
fragment.image = imageView.drawable
fragment.arguments = Bundle().also {
it.putString(ImageFragment.KEY_TRANSITION, imageView.transitionName)
}
// fragment.enterTransition = Fade()
// fragment.exitTransition = Fade()
supportFragmentManager
.beginTransaction()
.setReorderingAllowed(true)
.addSharedElement(imageView, imageView.transitionName)
.replace(R.id.container_test, fragment)
.commitNow()
}
图像片段布局
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black">
<ImageView
android:id="@+id/image_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitCenter"
/>
</FrameLayout>
ImageFragment
class ImageFragment : Fragment() {
private lateinit var binding: FragmentImageBinding
var image: Drawable?= null
companion object {
const val KEY_TRANSITION = "TRANSITION"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val transition = TransitionInflater.from(requireContext()).inflateTransition(android.R.transition.move)
sharedElementEnterTransition = transition
sharedElementReturnTransition = transition
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentImageBinding.inflate(inflater, container, false)
binding.imageView.transitionName = arguments?.getString(KEY_TRANSITION)
binding.imageView.setImageDrawable(image)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
view.setOnClickListener {
requireActivity().supportFragmentManager
.beginTransaction()
.remove(this)
.commit()
}
}
}
经过反复试验,我找到了原因。
我的初始片段静态放置在 XML 上,这阻止了片段管理器替换它。通过使用布局检查器,我发现新片段位于第一个片段的正下方。
基本上,解决方案是以编程方式添加第一个片段,以便片段管理器可以对其进行操作。