活动 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()
}
}
)
如果我没有忘记任何东西,这应该有用。如果没有请告诉我,我会在今天晚些时候尝试制作一个示例应用程序,因为我现在没有更多时间了。
有没有办法在 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()
}
}
)
如果我没有忘记任何东西,这应该有用。如果没有请告诉我,我会在今天晚些时候尝试制作一个示例应用程序,因为我现在没有更多时间了。