Digamos que eu tenho um linearLayout vertical com:
[v1]
[v2]
Por padrão, a v1 tem visibily = GONE. Gostaria de mostrar a v1 com uma animação de expansão e pressionar a v2 ao mesmo tempo.
Eu tentei algo assim:
Animation a = new Animation()
{
int initialHeight;
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final int newHeight = (int)(initialHeight * interpolatedTime);
v.getLayoutParams().height = newHeight;
v.requestLayout();
}
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
initialHeight = height;
}
@Override
public boolean willChangeBounds() {
return true;
}
};
Mas com esta solução, eu pisquei quando a animação é iniciada. Eu acho que é causado pela v1 exibindo o tamanho total antes da animação ser aplicada.
Com javascript, esta é uma linha do jQuery! Alguma maneira simples de fazer isso com o Android?
a.setDuration(((int)(initialHeight / v.getContext().getResources().getDisplayMetrics().density)) * 4)
v.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
ev.getLayoutParams().height = interpolatedTime == 1 ? targetHeight : (int)(targetHeight * interpolatedTime);
Isso funcionou para mim!Eu estava tentando fazer o que acredito ser uma animação muito semelhante e encontrei uma solução elegante. Este código pressupõe que você esteja sempre indo de 0-> h ou h-> 0 (h sendo a altura máxima). Os três parâmetros do construtor são view = a view a ser animada (no meu caso, uma webview), targetHeight = a altura máxima da view e down = um booleano que especifica a direção (true = expandindo, false = recolhendo).
fonte
Tropecei no mesmo problema hoje e acho que a verdadeira solução para essa pergunta é essa
Você precisará definir essa propriedade para todos os layouts superiores, envolvidos no turno. Se você agora definir a visibilidade de um layout como GONE, o outro ocupará o espaço à medida que o desaparecido o estiver liberando. Haverá uma animação padrão que é algum tipo de "desaparecimento", mas acho que você pode mudar isso - mas a última que ainda não testei por enquanto.
fonte
Peguei a solução da @LenaYan que não funcionou corretamente para mim ( porque estava transformando a vista em uma vista de altura 0 antes de recolher e / ou expandir ) e fiz algumas alterações.
Agora funciona muito bem , tomando a altura anterior do View e começando a expandir com esse tamanho. Desmoronar é o mesmo.
Você pode simplesmente copiar e colar o código abaixo:
Uso:
Bastante fácil!
Obrigado LenaYan pelo código inicial!
fonte
Uma alternativa é usar uma animação em escala com os seguintes fatores de escala para expansão:
e para desmoronar:
fonte
A resposta de Tom Esterez , mas atualizada para usar view.measure () corretamente de acordo com o Android, getMeasuredHeight retorna valores errados!
fonte
Ok, acabei de encontrar uma solução MUITO feia:
Sinta-se livre para propor uma solução melhor!
fonte
View.onMeause(widthMeasureSpec, heightMeasureSpec)
chamada, portanto as especificações de largura e altura devem ser trocadas.fonte
Se você não deseja expandir ou recolher todo o caminho - eis uma simples HeightAnimation -
Uso:
fonte
Adaptei a resposta atualmente aceita por Tom Esterez , que funcionou, mas tinha uma animação irregular e não muito suave. Minha solução substitui basicamente o
Animation
com aValueAnimator
, que pode ser equipado com umInterpolator
de sua escolha para obter vários efeitos, como ultrapassagem, rejeição, aceleração etc.Esta solução funciona muito bem com vistas que têm uma altura dinâmica (ou seja, usando
WRAP_CONTENT
), pois primeiro mede a altura real necessária e depois anima para essa altura.Você simplesmente chama
expand( myView );
oucollapse( myView );
.fonte
v.measure()
e agora ele está funcionando perfeitamente. Obrigado!Fazendo uso das funções de extensão Kotlin, isso é testado e a resposta mais curta
Basta chamar animateVisibility (expandir / recolher) em qualquer Visualização.
fonte
Adicionando a excelente resposta de Tom Esterez e a excelente atualização de Erik B , pensei em publicar minha própria opinião, compactando os métodos de expansão e contrato em um. Dessa forma, você poderia, por exemplo, ter uma ação como esta ...
... que chama o método abaixo e permite descobrir o que fazer depois de cada onClick () ...
fonte
Gostaria de acrescentar algo à resposta muito útil acima . Se você não souber a altura com a qual você terminará desde que suas visualizações .getHeight () retornem 0, faça o seguinte para obter a altura:
Onde DUMMY_HIGH_DIMENSIONS é a largura / altura (em pixels) que sua visualização é restrita a ... ter um número enorme é razoável quando a visualização é encapsulada com um ScrollView.
fonte
Este é um trecho que eu usei para redimensionar a largura de uma exibição (LinearLayout) com animação.
O código deve expandir ou diminuir de acordo com o tamanho do destino. Se você deseja uma largura de fill_parent, precisará passar o pai .getMeasuredWidth como largura de destino enquanto define o sinalizador como true.
Espero que ajude alguns de vocês.
}
fonte
resizeAnim.start()
. Também tentei com e semsetFillAfter(true)
.startAnimation(resizeAnim)
a vista.Para animação suave, use Handler com o método run ..... E aproveite a animação Expandir / Recolher
E ligue usando este código:
Outra solução é:
fonte
soluções combinadas de @Tom Esterez e @Geraldo Neto
fonte
Sim, concordei com os comentários acima. E, de fato, parece que a coisa certa (ou pelo menos a mais fácil?) A fazer é especificar (em XML) uma altura de layout inicial de "0px" - e então você pode passar outro argumento para "toHeight" ( por exemplo, a "altura final") para o construtor da sua subclasse de animação personalizada, por exemplo, no exemplo acima, seria algo como:
Enfim, espero que ajude! :)
fonte
Aqui está a minha solução. Eu acho que é mais simples. Ele apenas expande a visualização, mas pode ser facilmente estendido.
fonte
Penso que a solução mais fácil é definir
android:animateLayoutChanges="true"
a suaLinearLayout
e, em seguida, apenas mostrar / ocultar a visualização, definindo sua visibilidade. Funciona como um encanto, mas você não tem controle sobre a duração da animaçãofonte
Você está no caminho certo. Verifique se a v1 está configurada para ter uma altura de layout igual a zero antes do início da animação. Você deseja inicializar sua configuração para se parecer com o primeiro quadro da animação antes de iniciar a animação.
fonte
Esta foi a minha solução, meu
ImageView
cresce a partir100%
de200%
e regresso ao seu tamanho original, utilizando dois arquivos de animação dentrores/anim/
da pastaanim_grow.xml
anim_shrink.xml
Enviar um
ImageView
para o meu métodosetAnimationGrowShrink()
setAnimationGrowShrink()
método:fonte
Esta é uma solução de trabalho adequada, eu testei:
Exapnd:
Colapso:
Value Animator:
A vista v é a vista a ser animada, PARENT_VIEW é a vista do contentor que contém a vista.
fonte
Isso é realmente simples com o droidQuery . Para começar, considere este layout:
Podemos animar a altura até o valor desejado - digamos
100dp
- usando o seguinte código:Em seguida, use
droidQuery
para animar. A maneira mais simples é com isso:Para tornar a animação mais atraente, considere adicionar um facilitador:
Você também pode alterar a duração
AnimationOptions
usando oduration()
método ou manipular o que acontece quando a animação termina. Para um exemplo complexo, tente:fonte
Melhor solução para as visualizações de expansão / recolhimento:
fonte
onCheckedChanged
.Você pode usar um ViewPropertyAnimator com um leve toque. Para recolher, redimensione a vista para uma altura de 1 pixel e oculte-a. Para expandir, mostre-o e expanda-o à sua altura.
O pivô informa à vista de onde escalar, o padrão está no meio. A duração é opcional (padrão = 1000). Você também pode definir o interpolador para usar, como
.setInterpolator(new AccelerateDecelerateInterpolator())
fonte
Criei uma versão na qual você não precisa especificar a altura do layout, portanto, é muito mais fácil e limpo de usar. A solução é obter a altura no primeiro quadro da animação (ela está disponível naquele momento, pelo menos durante os meus testes). Dessa forma, você pode fornecer à View uma altura e margem inferiores arbitrárias.
Há também um pequeno hack no construtor - a margem inferior é definida como -10000, para que a exibição permaneça oculta antes da transformação (evita tremulações).
fonte
Use ValueAnimator:
fonte
mainView.getLayoutParams().height = height
.fonte
A classe pode ser chamada da seguinte maneira
fonte
Com base nas soluções de @Tom Esterez e @Seth Nelson (top 2), eu as simplifiquei. Além das soluções originais, não depende das opções do desenvolvedor (configurações de animação).
fonte