Para personalizar a execução da animação de transição de elemento compartilhado, há alguns que podem ser usados para mudar a transição dos elementos compartilhados.
Especificação de animação
Para mudar a especificação de animação usada para o movimento de tamanho e posição, especifique
um parâmetro boundsTransform
diferente em Modifier.sharedElement()
.
Isso fornece a posição inicial Rect
e a posição de destino Rect
.
Por exemplo, para fazer o texto no exemplo anterior se mover com um arco
movimento, especifique o parâmetro boundsTransform
para usar uma especificação keyframes
:
val textBoundsTransform = BoundsTransform { initialBounds, targetBounds -> keyframes { durationMillis = boundsAnimationDurationMillis initialBounds at 0 using ArcMode.ArcBelow using FastOutSlowInEasing targetBounds at boundsAnimationDurationMillis } } Text( "Cupcake", fontSize = 28.sp, modifier = Modifier.sharedBounds( rememberSharedContentState(key = "title"), animatedVisibilityScope = animatedVisibilityScope, boundsTransform = textBoundsTransform ) )
Você pode usar qualquer AnimationSpec
. Este exemplo usa uma especificação keyframes
.
boundsTransform
Modo de redimensionamento
Ao animar entre dois limites compartilhados, você pode definir o parâmetro resizeMode
.
como RemeasureToBounds
ou ScaleToBounds
. Esse parâmetro determina como
o elemento compartilhado transita entre os dois estados. ScaleToBounds
primeiro
mede o layout filho com as restrições de análise antecipada (ou destino). Em seguida, o
layout estável da filha é dimensionado para caber nos limites compartilhados.
ScaleToBounds
pode ser considerada uma "escala gráfica" entre os estados.
Já o RemeasureToBounds
mede e reorganiza o layout filho dos
sharedBounds
com restrições fixas animadas com base no tamanho de destino. A
reavaliação é acionada pela mudança de tamanho dos limites, que pode ser
de cada frame.
Para elementos combináveis Text
, o ScaleToBounds
é recomendado, porque ele evita o redimensionamento
e o fluxo de texto em linhas diferentes. Para limites com proporções
diferentes e se você quiser uma continuidade fluida entre os dois elementos compartilhados,
recomendamos o uso de RemeasureToBounds
.
A diferença entre os dois modos de redimensionamento pode ser vista nos exemplos a seguir:
|
|
---|---|
Pular para o layout final
Por padrão, ao fazer a transição entre dois layouts, o tamanho do layout é animado entre os estados inicial e final. Isso pode ser um comportamento indesejável quando com animação de conteúdo, como texto.
O exemplo a seguir ilustra o texto de descrição "Lorem Ipsum" entrar
na tela de duas maneiras diferentes. No primeiro exemplo, o texto é reflowado à medida que
entra à medida que o contêiner cresce. No segundo exemplo, o texto não
é reflowado à medida que cresce. Adicionar Modifier.skipToLookaheadSize()
impede o reflow
conforme ele cresce.
Não há Modifier.skipToLookahead() - observe o fluxo de texto "Lorem Ipsum" |
Modifier.skipToLookahead() - observe o argumento "Lorem Ipsum" o texto mantém o estado final no início da animação |
---|---|
Recorte e sobreposições
Um conceito importante ao criar elementos compartilhados no Compose é que, para para compartilhar entre diferentes elementos combináveis, a renderização do o elemento combinável é elevado a uma sobreposição de camada quando a transição é iniciada para sua correspondência no destino. O efeito disso é que ele vai escapar dos limites do pai e das transformações de camada (por exemplo, o Alfa e a escala).
Ele será renderizado sobre outros elementos de interface não compartilhados. Quando a transição for
concluída, o elemento será removido da sobreposição para o próprio DrawScope
.
Para recortar um elemento compartilhado em uma forma, use o Modifier.clip()
padrão
função. Coloque-o depois de sharedElement()
:
Image( painter = painterResource(id = R.drawable.cupcake), contentDescription = "Cupcake", modifier = Modifier .size(100.dp) .sharedElement( rememberSharedContentState(key = "image"), animatedVisibilityScope = this@AnimatedContent ) .clip(RoundedCornerShape(16.dp)), contentScale = ContentScale.Crop )
Se você precisar garantir que um elemento compartilhado nunca seja renderizado fora de um elemento pai
contêiner, é possível definir clipInOverlayDuringTransition
em sharedElement()
. De
Por padrão, para limites compartilhados aninhados, clipInOverlayDuringTransition
usa o clipe
caminho do sharedBounds()
pai.
oferecer suporte à manutenção de elementos da interface específicos, como uma barra na parte de baixo ou uma ação flutuante.
sempre na parte superior durante uma transição de elemento compartilhado, use
Modifier.renderInSharedTransitionScopeOverlay()
Por padrão,
mantém o conteúdo na sobreposição durante o tempo em que o modificador
transição está ativa.
Por exemplo, no Jetsnack, a BottomAppBar
precisa ser colocada sobre o
elemento compartilhado até que a tela não esteja visível. Adicionar o modificador
no elemento combinável o mantém elevado.
Sem |
Com |
---|---|
Às vezes, você pode querer que o elemento combinável não compartilhado também seja animado, assim como
permaneçam sobre os outros elementos combináveis antes da transição. Nesses casos, use
renderInSharedTransitionScopeOverlay().animateEnterExit()
para animar o
do elemento combinável enquanto a transição do elemento compartilhado é executada:
JetsnackBottomBar( modifier = Modifier .renderInSharedTransitionScopeOverlay( zIndexInOverlay = 1f, ) .animateEnterExit( enter = fadeIn() + slideInVertically { it }, exit = fadeOut() + slideOutVertically { it } ) )
No caso raro em que você quer que o elemento compartilhado não seja renderizado em uma
sobreposição, defina renderInOverlayDuringTransition
em sharedElement()
como falso.
Notificar layouts irmãos sobre mudanças no tamanho do elemento compartilhado
Por padrão, sharedBounds()
e sharedElement()
não notificam o contêiner
pai sobre nenhuma mudança de tamanho à medida que o layout transita.
Para propagar as mudanças de tamanho para o contêiner pai durante a transição,
mude o parâmetro placeHolderSize
para PlaceHolderSize.animatedSize
. Isso
faz com que o item aumente ou diminua. Todos os outros itens do layout respondem
a mudança.
|
(Observe como os outros itens na lista se movem para baixo em resposta ao crescimento de um item) |
---|---|