Muchos desarrolladores para Android enfrentaron el problema de implementar animaciones y transiciones al abrir nuevos fragmentos. Se nos invita a usar ya sea agregando fragmentos al contenedor, superponiéndolos uno encima del otro, o reproduciéndolos (reemplazando un fragmento por otro). La repetición tiene cuatro tipos de animaciones:
Vive todo se parece a esto:.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()

El problema con las repeticiones es que a) el fragmento anterior se destruye, b) no hay forma de establecer una acción para cerrar el fragmento con un gesto (por ejemplo, como se implementa en Google Inbox).
Agregar fragmentos a la pila (agregar) le permite usar animaciones solo para que el fragmento se abra, la parte posterior estará inmóvil.
Y todo esto, por supuesto, va acompañado de una representación pobre y marcos rotos.
Como resultado, incluso las aplicaciones grandes como VKontakte o Instagram no usan fragmentos de animaciones en absoluto en sus aplicaciones.
Hace un año y medio, Telegram presentó Telegram x (una versión de prueba de su cliente). Resolvieron este problema así:

Aquí, se implementa la animación de los fragmentos delantero y trasero, así como la capacidad de cerrar fragmentos con un gesto.
Logré hacer algo similar y me gustaría compartir mi método de abrir fragmentos:

Entonces, cree la clase 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 }
Ahora tenemos nuestro navegador, que usamos como contenedor para todos los fragmentos de nuestra actividad:
<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"/>
Fondo conjunto negro. Esto es necesario para simular la sombra en el fragmento cerrado. Además será más claro.
Ahora necesitamos un adaptador en el que colocaremos los fragmentos:
class NavigatorAdapter(val fragmentManager: FragmentManager) : FragmentStatePagerAdapter(fragmentManager) {
Inmediatamente cree un transformador para nuestro navegador:
class NavigatorPageTransformer : ViewPager.PageTransformer { override fun transformPage(view: View, position: Float) {
Ahora, ¡lo más interesante! Prescribimos las acciones necesarias para abrir fragmentos en nuestra Actividad:
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)
Eso, de hecho, es todo. Ahora en cualquier fragmento llamamos al método de Activiti:
(activity as MainActivity).addFragment(ConversationFragment())
Y al deslizar hacia la derecha, él mismo será eliminado de la pila con la ayuda de nuestro oyente OnPageChangeListener.
Este método no es ideal, tal vez se abrirán algunas dificultades en el desarrollo posterior, pero aún no he encontrado ningún problema de usabilidad, tal vez los desarrolladores experimentados me corrijan o me digan algo. Puedes ver cómo funciona todo en un ejemplo real aquí .