提问者:小点点

活动1内部的fragment1和活动2内部的fragment2之间的共享转换


有没有办法在活动1内部的fragment1和活动2内部的fragment2之间进行共享转换?

我试过这样做:

    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内,还是有任何变通办法?谢谢


共1个答案

匿名用户

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

守则:你在第一个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()
        }
    }
)

如果我什么都没忘,这应该管用。如果没有请告诉我,我会尝试做一个示例应用程序晚些时候,因为我没有更多的时间现在。