许多Android开发人员在打开新片段时都面临实现动画和过渡的问题。 邀请我们使用以下方法:将片段添加到容器中,将片段彼此叠加,或者重播(将一个片段替换为另一个片段)。 重播有四种动画:
直播一切看起来像这样:.beginTransaction() .setCustomAnimations( R.anim.enter_from_left, // 2 R.anim.exit_to_right, // 1 R.anim.enter_from_right, // 1 R.anim.exit_to_left) // 2 .replace(R.id.container, myFragment) .commit()

重播的问题是:a)先前的片段已被破坏,b)无法设置动作以手势关闭片段(例如,在Google Inbox中实现)。
将片段添加到堆栈(添加)可让您仅对要打开的片段使用动画,后面的片段将保持静止。
当然,所有这些都伴随着不良的渲染和残破的帧。
结果,即使是大型应用程序(如VKontakte或Instagram)也根本不会在其应用程序中使用片段动画。
一年半以前,Telegram推出了Telegram x(客户端的测试版本)。 他们这样解决了这个问题:

在这里,实现了前后片段的动画以及通过手势关闭片段的功能。
我设法做了类似的事情,我想分享一下我打开片段的方法:

因此,创建NavigatorViewPager类:
class NavigatorViewPager : ViewPager { init { init() } constructor(context: Context) : super(context) constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet) override fun canScrollHorizontally(direction: Int): Boolean { return false }
现在我们有了导航器,我们将其用作活动中所有片段的容器:
<info.yamm.project2.navigator.NavigatorViewPager xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/navigator_view_pager" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/black" android:fitsSystemWindows="false" tools:context=".activities.MainActivity"/>
背景设置为黑色。 这是模拟封闭片段上的阴影所必需的。 进一步将更加清楚。
现在我们需要一个适配器,在其中放置片段:
class NavigatorAdapter(val fragmentManager: FragmentManager) : FragmentStatePagerAdapter(fragmentManager) {
立即为我们的导航器创建一个Transformer:
class NavigatorPageTransformer : ViewPager.PageTransformer { override fun transformPage(view: View, position: Float) {
现在-最有趣! 我们规定了在活动中打开片段的必要操作:
class MainActivity : BaseActivity() { private lateinit var navigatorAdapter: NavigatorAdapter private lateinit var navigatorViewPager: NavigatorViewPager private lateinit var mainFragment: MainFragment override fun onCreate(savedInstanceState: Bundle?) { setTheme(info.yamm.project2.R.style.AppTheme)
实际上,仅此而已。 现在在任何片段上,我们从Activiti调用方法:
(activity as MainActivity).addFragment(ConversationFragment())
向右滑动时,将在我们的OnPageChangeListener侦听器的帮助下将他本人从堆栈中删除。
这种方法并不理想,在进一步的开发中可能会遇到一些陷阱,但我尚未发现任何可用性问题,也许经验丰富的开发人员会纠正我或告诉我一些事情。 在这里,您可以在一个真实的示例中看到它是如何工作的。