Muitos desenvolvedores para Android enfrentaram o problema de implementar animações e transições ao abrir novos fragmentos. Somos convidados a adicionar fragmentos ao contêiner, colocá-los em camadas uns sobre os outros ou reproduzir (substituindo um fragmento por outro). A reprodução tem quatro tipos de animações:
Live it tudo se parece com isso:.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()

O problema com replays é que: a) o fragmento anterior é destruído; b) não há como definir uma ação para fechar o fragmento com um gesto (por exemplo, conforme implementado na Caixa de entrada do Google).
Adicionar fragmentos à pilha (adicionar) permite que você use animações apenas para que o fragmento seja aberto; a parte traseira ficará imóvel.
E tudo isso, é claro, é acompanhado por uma renderização ruim e quadros quebrados.
Como resultado, mesmo aplicativos grandes como o VKontakte ou o Instagram não usam animações de fragmento em seus aplicativos.
Há um ano e meio, o Telegram introduziu o Telegram x (uma versão de teste de seu cliente). Eles resolveram esse problema assim:

Aqui, a animação dos fragmentos dianteiro e traseiro é implementada, bem como a capacidade de fechar fragmentos com um gesto.
Consegui fazer algo semelhante e gostaria de compartilhar meu método de abertura de fragmentos:

Portanto, crie a classe 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 }
Agora temos o nosso Navegador, que usamos como um contêiner para todos os fragmentos em nossa Atividade:
<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"/>
Plano de fundo conjunto preto. Isso é necessário para simular a sombra no fragmento fechado. além disso, será mais claro.
Agora precisamos de um adaptador no qual colocaremos os fragmentos:
class NavigatorAdapter(val fragmentManager: FragmentManager) : FragmentStatePagerAdapter(fragmentManager) {
Crie imediatamente um Transformer para o nosso Navegador:
class NavigatorPageTransformer : ViewPager.PageTransformer { override fun transformPage(view: View, position: Float) {
Agora - o mais interessante! Nós prescrevemos as ações necessárias para abrir fragmentos em nossa Atividade:
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)
Isso, de fato, é tudo. Agora, em qualquer fragmento, chamamos o método da Activiti:
(activity as MainActivity).addFragment(ConversationFragment())
E ao deslizar para a direita, ele próprio será removido da pilha com a ajuda de nosso ouvinte OnPageChangeListener.
Esse método não é ideal, talvez algumas armadilhas sejam abertas em desenvolvimento adicional, mas ainda não encontrei nenhum problema de usabilidade, talvez desenvolvedores experientes me corrijam ou me digam algo. Você pode ver como tudo funciona em um exemplo real aqui .