Polir a IU no Android: StateListAnimator

Olá, Habr! Em antecipação ao início do curso “Desenvolvedor Android. Profissional ”, preparamos para você uma tradução de outro material interessante.








Passamos a maior parte do tempo de desenvolvimento de nosso aplicativo Android sem funcionar na interface do usuário - apenas exibimos e começamos a escrever o código. Percebi que a maioria de nós realmente não se preocupa com a interface do usuário. E acho que isso está fundamentalmente errado. Os desenvolvedores de aplicativos móveis também precisam cuidar da UI / UX. Não estou dizendo “seja um especialista em IU móvel”, mas você deve entender a linguagem de design e seus conceitos.



Eu já escrevi um artigo sobre sombras no design de material e recebi muitas críticas boas. Eu quero agradecer a todos vocês. “Mastering Shadows in Android” fala sobre elevação e sombra no Android. No mesmo lugar, mostrei como complementei minha biblioteca de IU de software livre com eles. ( Layout de dimensionamento ).



Neste artigo, quero melhorar minha biblioteca usando StateListAnimator e mostrar passo a passo como vou fazer isso.



Conteúdo



Este artigo cobre os seguintes tópicos:





Estados drawable



O Android tem 17 estados diferentes para Drawable.







Podemos nunca ter conhecido alguns deles. Não vou me aprofundar em todos os estados. Na maioria dos casos, usamos o pressed, enabled, windows focused, checkede assim por diante. D. Se não declarar o estado de drawable, presume-se que este estado por padrão no Android.



Precisamos entender esses estados para escrever nosso próprio StateListDrawable .



StateListDrawable



É essencialmente uma lista de itens drawable, onde cada item tem seu próprio estado. Para criar um StateListDrawable, precisamos criar um arquivo XML em uma pasta res/drawable.



<item android:drawable="@drawable/i" android:state_pressed="true"/>


Este é um item. Possui duas propriedades. Drawable e State .



<selector>
   <item
       android:drawable="@drawable/p"
       android:state_pressed="true"/>
   <item
       android:drawable="@drawable/default"/>
</selector>


Isso é StateListDrawable. Se não declararmos um estado para um elemento, como mencionei anteriormente, isso significa que este é o estado padrão .



Posso usar o ShapeDrawable?



Sim. Em vez de usar android: drawable, você pode adicionar uma forma arbitrária ao seu elemento. Aqui está um elemento com um ShapeDrawable .





StateListDrawable



Você pode usar StateListDrawable a partir do nível de API 1. Portanto, não há restrição de nível de API para StateListDrawable.



<View
   android:layout_width="50dp"
   android:layout_height="50dp"
   android:foreground="@drawable/state_list_drawable"
   android:clickable="true"/>


Isso é tudo. Agora nossa visão tem um estado. Quando o usuário clica nele, sua cor muda. Quando o usuário o liberar, ele terá um estado e uma cor padrão.



Mas espere um segundo. Clicável ? Por que adicionamos este atributo? Também precisamos adicioná-lo? Sim. Mas apenas para visualizações personalizadas. Leva tempo para descobrir. Os botões funcionam bem sem adicionar clicáveis, porque são clicáveis por padrão . Mas se você deseja usar StateListDrawable para View, ImageView, Custom View, etc., você precisa adicionar um atributo clicável .




StateListDrawable



Eu adicionei StateListDrawable neste commit . É semelhante ao exemplo que dei acima. Quando o usuário clica no layout, ele é colorido. Mas vamos melhorar isso com StateListAnimator.



StateListAnimator



Lembre-se de que quando você clica em FloatingActionButton, seu valor Z aumenta devido à animação. Este é um StateListAnimator fora da tela, por assim dizer. Alguns widgets de design de material têm seu próprio StateListAnimator dentro.



Vamos esclarecer isso com uma pergunta sobre StackOverflow.







(Como remover borda / sombra dos botões de pirulito).



Se os widgets do Material Design tiverem seu próprio StateListAnimator dentro, podemos defini-los como null para remover essa função (não recomendado, foi projetado por um motivo.) E agora a resposta parece muito mais lógica.





(Lollipop tem uma pequena função desagradável chamada stateListAnimatorque lida com a altura dos botões, produzindo sombras.



Remova stateListAnimatorpara se livrar das sombras.



Você tem várias opções de como fazer isso:



No código:



button.setStateListAnimator (null);)






Então, como podemos criá-lo?



Para entender StateListAnimator, precisamos entender a animação de propriedade . Não vou me aprofundar na animação de propriedades neste artigo. Mas pelo menos quero mostrar o básico.



Propriedades de animação



Aqui está o exemplo mais simples de uma propriedade em um objeto. X é uma propriedade.



class MyObject{
 
   private int x;
 
   public int getX() {
       return x;
   }
 
   public void setX(int x) {
       this.x = x;
   }
}


O sistema de animação de propriedade é uma estrutura robusta que permite animar quase tudo . Você pode especificar animações para qualquer alteração de propriedade do objeto ao longo do tempo, independentemente de ele ser exibido na tela ou não . Uma animação de propriedade altera o valor de uma propriedade (um campo em um objeto) durante um período de tempo especificado.







X é uma propriedade . T é a hora . Durante a animação, a propriedade X é atualizada no horário especificado. Em geral, é assim que funciona a animação de propriedades. Em vez de uma caixa, pode haver uma visualização ou qualquer objeto.



ValueAnimatorÉ a classe base para animar propriedades. Você pode configurar um ouvinte para atualizar o ValueAnimator e observar as alterações de propriedade.



ObjectAnimator é uma classe que herda deValueAnimator . Você pode usar ObjectAnimator se o seguinte for mais adequado para você:



  • Você tem um objeto (qualquer classe com alguma propriedade).
  • Você não quer assistir o ouvinte ValueAnimator.
  • Você deseja atualizar a propriedade do objeto automaticamente.


Portanto, se temos uma visão (que é um objeto) e queremos atualizar a propriedade da visão (coordenada x, coordenada y, rotação, translação ou qualquer outra propriedade para a qual a visão tenha um getter / setter), podemos usar o ObjectAnimator . Vamos continuar criando o StateListAnimator.



<selector>
 
   <item android:state_pressed="true">
      <objectAnimator
           android:duration="200"
           android:propertyName="translationZ"
           android:valueTo="6dp"
           android:valueType="floatType" />
   </item>
 
   <item>
      <objectAnimator
           android:duration="200"
           android:propertyName="translationZ"
           android:valueTo="0dp"
           android:valueType="floatType"/>
   </item>
 
</selector>




O botão FAB anima sua propriedade "translationZ" quando pressionado e liberado.



Como eu disse antes, podemos usar a propriedade do objeto diretamente, sem observar as alterações no animador. Cada visualização possui uma propriedade translationZ. Desta forma, podemos animar diretamente o translationZ usando o ObjectAnimator.



Também podemos combinar vários <objectAnimator>s em <set>. Vamos alterar mais uma propriedade da View. Escala X e escala Y .



Aqui está o resultado! Agora também cresce quando clicado pelo usuário. E aqui está o commit .







Você também pode definir outras propriedades em seu animator.xml. Você pode encontrar mais informações sobre como usar o ObjectAnimator aqui.



Isso é tudo. Estou planejando escrever mais sobre ValueAnimator e ObjectAnimator. Esta é uma ótima API para animar um objeto.



Codificação bem-sucedida!






All Articles