活动 1 内的片段和活动 2 内的片段之间的共享转换

Shared transition between fragment1 inside activity1 and fragment2 inside activity2

有没有办法在 activity1 内的片段 1 和 activity2 内的片段 2 之间进行共享转换?

我试过这样实现:

    val intent = Intent(this, RecipeActivity::class.java)
    intent.putExtra("recipeId", recipeId)
    val elem1 =
        Pair<View, String>(itemView.findViewById(R.id.recipe_preview), "preview")
    val elem2 =
        Pair<View, String>(itemView.findViewById(R.id.recipe_title), "title")
    val elem3 =
        Pair<View, String>(itemView.findViewById(R.id.recipe_rating_stars), "rating_stars")
    val elem4 =
        Pair<View, String>(itemView.findViewById(R.id.recipe_rating), "rating")
    val elem5 =
        Pair<View, String>(itemView.findViewById(R.id.recipe_description), "description")
    val elem6 =
        Pair<View, String>(itemView.findViewById(R.id.author_avatar), "avatar")
    val options =
        ActivityOptionsCompat.makeSceneTransitionAnimation(
            this, elem1, elem2, elem3, elem4, elem5, elem6
        )
    startActivity(intent, options.toBundle())

但是效果不是很好。我是否必须重新设计我的应用程序以便将这两个片段放在一个 activity 中,或者是否有任何解决方法?谢谢

想法:暂停事务,直到目标片段完全加载、创建并即将绘制。然后继续交易。

代码: 您在第一个 activity 中所做的一切都可以,我们不会碰它。 您的 activity 要做的第一件事就是停止交易。因此,您需要在第二个 activity 的 onCreate() 中调用 supportPostponeEnterTransition()。这将告诉 android 等待交易,直到你告诉它开始它。

其次,你需要知道片段何时被绘制。在我的用例中,我在 ViewPager 中显示了一些片段,这让事情变得容易多了,因为你可以向它添加一个 ViewTreeObserver 并等待 ViewPager 加载,因为你知道此时片段已经创建并且基本上绘制了即使你看不到他们。当以正常方式使用 frgaments 时,您需要一些技巧。

重要提示:从现在开始的一切都没有经过测试,但理论上它应该可以工作。

在你的片段中你做这样的事情:

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    return inflater.inflate(R.layout.fragment_home, container, false)
}

你应该这样做:

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    val view = inflater.inflate(R.layout.fragment_home, container, false)
    return view
}

您需要片段的根视图,因为我们会将 ViewTreeObserver 添加到其中。

但在此之前,您需要在 FragmentClass 中创建一个接口或将方法添加到您已有的接口中:

interface FragmentListener {
   fun resumeTransaction()
}

您需要在 activity:

中实现它
override fun resumeTransaction() {
    supportStartPostponedEnterTransition()
}

在您的片段中,我们需要将 Activity 作为侦听器。在 onAttach 中执行以下操作:

try {
    // Instantiate the FragmentListener so we can send the event to the host
    listener = context as FragmentInterface
} catch (e: ClassCastException) {
    // The activity doesn't implement the interface, throw exception
    throw ClassCastException((context.toString() + " must implement FragmentInterface"))
}

现在我们回到 ViewTreeObserver。在 onCreateView 你这样做:

viewPager.viewTreeObserver.addOnPreDrawListener(
    object : ViewTreeObserver.OnPreDrawListener {
        override fun onPreDraw(): Boolean {
            listener.resumeTransaction()
        }
    }
)

如果我没有忘记任何东西,这应该有用。如果没有请告诉我,我会在今天晚些时候尝试制作一个示例应用程序,因为我现在没有更多时间了。