Amigos, ótimo toda sexta-feira. Queremos compartilhar com você a tradução de um artigo preparado especialmente para os alunos do curso 
“Android-developer. Curso avançado . 
” Boa leitura.

Como declarativamente estilizar o texto no Android.
 Ilustração de Virginia Poltrack
Ilustração de Virginia PoltrackTextView em aplicativos Android fornece vários atributos para estilizar o texto e várias maneiras de aplicá-lo. Esses atributos podem ser configurados diretamente no layout, aplicar um estilo à visualização ou tema ao layout ou, se você desejar, definir textAppearance. Mas o que isso deve ser usado? E o que acontece se você combiná-los? 
 O que e quando usar?
O que e quando usar?Este artigo descreve várias abordagens para estilização declarativa de texto (ou seja, quando você define estilos em um arquivo XML), discute o escopo e a prioridade de cada método.
tl; dr;
Você 
deve ler o post inteiro, mas aqui está um resumo.
Lembre-se da ordem de prioridade dos vários métodos de estilo - se você estiver tentando estilizar algum texto e não encontrar os resultados esperados, provavelmente suas alterações serão substituídas por algo com uma prioridade mais alta nesta hierarquia:
 Hierarquia de métodos de estilo de texto
Hierarquia de métodos de estilo de textoEu sugeriria o seguinte procedimento para estilizar:
- Defina qualquer estilo de aplicativo no textViewStylecomo o estilo padrão para o seu tema.
- Instale o conjunto (pequeno) de TextAppearanceque seu aplicativo usará (ou usará / herdará dos estilos MaterialComponent) e faça referência a eles diretamente da sua exibição
- Crie um styledefinindo atributos não suportados peloTextAppearance(que eles mesmos determinarão um dos seusTextAppearance).
- Execute qualquer estilo exclusivo diretamente no layout.
Mostre algum estilo
Você pode definir diretamente os atributos do 
TextView no layout, mas essa abordagem pode ser mais entediante e insegura. Imagine que dessa maneira você está tentando atualizar a cor de todos os TextViews no aplicativo. Como em todas as outras visualizações, você pode (e deve!) Usar estilos para garantir consistência, reutilização e facilidade de atualização. Para esse fim, recomendo criar estilos para texto sempre que você desejar aplicar o mesmo estilo a várias visualizações. Isso é extremamente simples e amplamente suportado pelo sistema de exibição do Android.
O que acontece quando você estiliza a vista? Se você já escreveu sua exibição personalizada, provavelmente viu a chamada para 
context.obtainStyledAttributes (AttributeSet, int [], int, int) . Assim, o sistema de visualização no Android passa para a visualização os atributos especificados no layout. O parâmetro 
AttributeSet , de fato, pode ser considerado como um mapa dos parâmetros XML que você especifica em seu layout. Se o AttributeSet definir o estilo, o 
estilo será lido primeiro e, em seguida, os atributos especificados diretamente na exibição serão aplicados a ele. Assim, chegamos à primeira regra de prioridade.
Exibir → EstiloOs atributos definidos diretamente na visualização sempre "prevalecem" e substituem os atributos definidos no estilo. Observe que uma 
combinação de atributos de estilo e exibição é aplicada; definir um atributo na exibição, que também é especificado no estilo, 
não cancela o estilo inteiro. Note-se também que, na sua opinião, não existe uma maneira real de determinar de onde vem a estilização; Isso é decidido pelo sistema de visualização para você uma vez em uma chamada semelhante. Você não pode obter as duas opções e escolher.
Embora os estilos sejam extremamente úteis, eles têm suas limitações. Uma delas é que você pode aplicar apenas um estilo à visualização (em oposição a algo como CSS, onde você pode aplicar várias classes). 
TextView , no entanto, tem um truque: fornece o atributo 
TextAppearance , que funciona de maneira semelhante ao 
style . Se você 
style texto por meio do 
TextAppearance , deixe o atributo 
style livre para outros estilos, o que parecerá prático. Vamos dar uma olhada no que 
TextAppearance e como ele funciona.
Textappearance
Não há nada mágico no 
TextAppearance (por exemplo, um modo secreto para aplicar vários estilos que você não deveria saber !!!!), o 
TextView evita que você trabalhe desnecessariamente. Vamos dar uma olhada no construtor 
TextView para entender o que está acontecendo.
 TypedArray a = theme.obtainStyledAttributes(attrs, com.android.internal.R.styleable.TextViewAppearance, defStyleAttr, defStyleRes); TypedArray appearance = null; int ap = a.getResourceId(com.android.internal.R.styleable.TextViewAppearance_textAppearance, -1); a.recycle(); if (ap != -1) { appearance = theme.obtainStyledAttributes(ap, com.android.internal.R.styleable.TextAppearance); } if (appearance != null) { readTextAppearance(context, appearance, attributes, false); appearance.recycle(); }  
Então, o que está acontecendo aqui? Basicamente, o 
TextView primeiro verifica se você especificou 
android:textAppearance ; 
android:textAppearance caso, ele carrega esse estilo e aplica todas as propriedades listadas lá. Mais tarde, ele carrega todos os atributos da visualização (que ele lembra, incluindo o estilo) e os aplica. Então chegamos à segunda regra de prioridade:
Exibir → Estilo → Aparência de textoComo a aparência do texto é marcada primeiro, qualquer atributo definido diretamente na exibição ou no estilo o substituirá.
Com o 
TextAppearance , há outra 
TextAppearance : ele suporta um 
subconjunto dos atributos de estilo que o 
TextView oferece. Para entender melhor o que quero dizer, vamos voltar a esta linha:
obtainStyledAttributes(ap, android.R.styleable.TextAppearance);Vimos a versão 
receiveStyledAttributes com 4 argumentos, essa versão com 2 argumentos é um pouco diferente dela. Ela analisa o estilo fornecido (conforme definido pelo primeiro 
id parâmetro) e o filtra apenas de acordo com os atributos no estilo que aparecem no segundo parâmetro, o array 
attrs . O 
android.R.styleable.TextAppearance tão estiloso que define o escopo do 
TextAppearance . Observando essa definição, vemos que o 
TextAppearance suporta muitos, 
mas não todos, atributos que o 
TextView suporta .
 <attr name="textColor" /> <attr name="textSize" /> <attr name="textStyle" /> <attr name="typeface" /> <attr name="fontFamily" /> <attr name="textColorHighlight" /> <attr name="textColorHint" /> <attr name="textColorLink" /> <attr name="textAllCaps" format="boolean" /> <attr name="shadowColor" format="color" /> <attr name="shadowDx" format="float" /> <attr name="shadowDy" format="float" /> <attr name="shadowRadius" format="float" /> <attr name="elegantTextHeight" format="boolean" /> <attr name="letterSpacing" format="float" /> <attr name="fontFeatureSettings" format="string" /> 
Atributos de estilo suportados pelo TextAppearanceAqui estão alguns atributos do 
TextView que não estão incluídos no 
TextAppearance : 
lineHeight[Multiplier|Extra] , 
lines , 
breakStrategy e 
breakStrategy . 
TextAppearance funciona no nível do caractere, não no nível do parágrafo; portanto, os atributos que afetam o layout inteiro não são suportados.
Portanto, 
TextAppearance muito útil, pois permite definir um estilo orientado para os atributos de estilização de texto e deixa o 
style à vista livre para outros fins. No entanto, ele tem um escopo limitado e está na parte inferior da cadeia de prioridades, portanto, não se esqueça das limitações.
Padrões razoáveis
Quando analisamos como a visualização Android resolve atributos ( 
context.obtainStyledAttributes ), na verdade simplificamos um pouco. Ela chama 
theme.obtainStyledAttributes (usando o 
Theme Context atual 'a). Ao verificar o 
link , a ordem de prioridade que examinamos anteriormente é mostrada e mais 2 locais são indicados que ele está procurando para resolver atributos: o estilo padrão da visualização e o tema.
Ao determinar o valor final de um atributo específico, quatro parâmetros de entrada entram em jogo: 
- Qualquer valor de atributo neste AttributeSet.
- O recurso de estilo especificado no AttributeSet (chamado "style").
- O estilo padrão especificado por defStyleAttr e defstyleres
- Valores básicos neste segmento.
Ordem de prioridade de estilo a partir da documentação do temaVoltaremos aos temas, mas vamos dar uma olhada nos estilos padrão primeiro. Qual é esse estilo padrão? Para responder a essa pergunta, acho que seria útil fazer uma pequena saída do tema 
TextView e dar uma olhada em um simples 
Button . Quando você insere 
< Button > no layout, ele se parece com isso.
 Botão Padrão
Botão PadrãoPorque Se você olhar o código fonte do 
Button , verá que ele é bastante escasso:
 public class Button extends TextView { public Button(Context context) { this(context, null); } public Button(Context context, AttributeSet attrs) { this(context, attrs, com.android.internal.R.attr.buttonStyle); } public Button(Context context, AttributeSet attrs, int defStyleAttr) { this(context, attrs, defStyleAttr, 0); } public Button(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } @Override public CharSequence getAccessibilityClassName() { return Button.class.getName(); } @Override public PointerIcon onResolvePointerIcon(MotionEvent event, int pointerIndex) { if (getPointerIcon() == null && isClickable() && isEnabled()) { return PointerIcon.getSystemIcon(getContext(), PointerIcon.TYPE_HAND); } return super.onResolvePointerIcon(event, pointerIndex); } } 
Isso é tudo! Aqui está toda a classe (sem comentários). Você pode conferir 
você mesmo 
aqui . Vou esperar Então, de onde vêm os antecedentes, letras maiúsculas, ondulações etc.? Você pode ter perdido, mas tudo será definido no construtor com 2 argumentos; aquele que é chamado quando o layout é obtido do XML. Este é o último parâmetro que define 
defaultStyleAttr em 
com.android.internal.R.attr.buttonStyle . Este é o estilo padrão, que é essencialmente um ponto de referência indireto, permitindo que você especifique o estilo padrão. Ele não aponta diretamente para o estilo, mas permite que você aponte para um dos especificados em seu tópico que ele verificará ao resolver atributos. E é exatamente isso que todos os temas dos quais você geralmente herda fazem para fornecer a aparência dos widgets padrão. Por exemplo, se você examinar o tópico Material, ele define 
@style/Widget.Material.Light.Button , e é esse estilo que fornece todos os atributos que 
theme.obtainStyledAttributes se você não especificou mais nada.
De volta ao 
TextView , ele também oferece um estilo padrão: 
textViewStyle . Isso pode ser muito conveniente se você deseja aplicar alguns estilos a cada TextView no seu aplicativo. Suponha que você queira definir o espaçamento de linha padrão como 1,2. Você pode fazer isso com 
style/TextAppearance e tentar aplicá-lo durante uma revisão de código (ou talvez até com uma regra personalizada elegante no Lint), mas você precisa estar atento e recrutar novos membros da equipe , tenha cuidado com a refatoração, etc.
Uma abordagem melhor seria especificar seu próprio estilo padrão para todos os 
TextView no aplicativo, definindo o comportamento desejado. Você pode fazer isso definindo seu próprio estilo para 
textViewStyle , que é herdado da plataforma ou de 
MaterialComponents/AppCompat por padrão.
 <style name="Theme.MyApp" parent="@style/Theme.MaterialComponents.Light"> ... <item name="android:textViewStyle">@style/Widget.MyApp.TextView</item></style> <style name="Widget.MyApp.TextView" parent="@android:style/Widget.Material.TextView"> <item name="android:textAppearance">@style/TextAppearance.MyApp.Body</item> <item name="android:lineSpacingMultiplier">@dimen/text_line_spacing</item> </style> 
Com isso em mente, nossa regra de prioridade assume a forma:
Ver -> Estilo -> Estilo Padrão -> Aparência de TextoComo parte da resolução dos atributos do sistema de exibição, esse espaço é preenchido após os estilos (para que tudo no estilo seja cancelado pelo estilo aplicado ou pelos atributos de exibição por padrão), mas ainda substitua a aparência do texto. Os estilos padrão podem ser muito convenientes. Se você decidir escrever sua própria exibição personalizada, ela poderá ser uma maneira poderosa de implementar o comportamento padrão, facilitando a personalização.
Se você herdar o widget e não especificar seu próprio estilo padrão, use o estilo de classe pai padrão nos construtores (não passe apenas 0). Por exemplo, se você herdar de 
AppCompatTextView e gravar seu próprio construtor com 2 argumentos, passe 
android.R.attr.textViewStyle defaultStyleAttr ( 
como aqui ), caso contrário você perderá o comportamento da classe pai.
Temas
Como mencionado anteriormente, existe outra (última, prometo) maneira de fornecer informações sobre o estilo. Outro 
theme.obtainStyledAttributes abordará diretamente o próprio tópico. Ou seja, se você adicionar um atributo de estilo ao seu tema, por exemplo 
android:textColor , o sistema de exibição o selecionará como último recurso. Como regra, é uma má idéia misturar atributos de tema e atributos de estilo, ou seja, o que você aplica diretamente à exibição, como regra, nunca deve ser definido para o tema (e vice-versa), mas existem algumas exceções raras.
Um exemplo seria quando você tenta alterar a fonte em todo o aplicativo. Você pode usar um dos métodos descritos acima, mas o ajuste manual dos estilos / aparência do texto em qualquer lugar será monótono e inseguro, e os estilos padrão funcionarão apenas no nível do widget; As subclasses podem substituir esse comportamento; por exemplo, os botões definem seu próprio 
android:buttonStyle , que seu 
android:textViewStyle não atenderá. Em vez disso, você pode especificar a fonte no seu tema:
 <style name="Theme.MyApp" parent="@style/Theme.MaterialComponents.Light"> ... <item name="android:fontFamily">@font/space_mono</item> </style> 
Agora, qualquer visualização que suporte esse atributo o buscará se não for substituída por algo com uma prioridade mais alta:
Exibir → Estilo → Estilo padrão → Tema → Aparência de textoNovamente, como isso faz parte do sistema de estilo de exibição, ele substituirá tudo o que é fornecido em forma de texto, mas será substituído por quaisquer atributos mais específicos.
Lembre-se desta prioridade. No nosso exemplo, com uma fonte para todo o aplicativo, você pode esperar que a 
Toolbar escolha essa fonte, pois ela contém o título, que é um 
TextView . A própria classe Barra de Ferramentas, no entanto, define um estilo padrão que contém 
titleTextAppearance , que define 
android:fontFamily , e o define diretamente no cabeçalho do 
TextView , substituindo o valor do nível do tema. Os estilos no nível do tópico podem ser úteis, mas fáceis de substituir, portanto, verifique se eles foram aplicados corretamente.
Bônus: problemas não resolvidos
Este artigo inteiro foi dedicado ao design declarativo do texto no nível da visualização, ou seja, como estilizar todo o 
TextView durante o preenchimento. Qualquer estilo aplicado após o preenchimento (por exemplo, 
textView.setTextColor(…) ) substituirá o estilo declarativo. 
TextView também suporta estilos menores através do 
Span . Não vou entrar neste tópico, como é descrito em detalhes nos artigos de 
Florina Muntenescu .
→ 
Estilo de texto fantasmático com vãos→ 
Vãos compreensivosMencionarei isso por questões de integridade, tendo em mente que o estilo e a extensão do programa estarão no topo da ordem de prioridade:
Extensão → Setters → Exibir → Estilo → Estilo padrão → Tema → Aparência de textoEscolha o seu estilo
Embora existam várias maneiras de estilizar seu texto, entender as diferenças entre os métodos e suas limitações ajuda a encontrar a ferramenta certa para uma tarefa específica ou a entender por que um método tem precedência sobre outro.
Tenha um bom estilo de texto!
Convidamos a todos para um 
webinar gratuito no âmbito do qual conheceremos a estrutura DI Dagger 2: estudaremos como o Dagger2 gera código, lidaremos com as anotações JSR 330 e as construções Dagger2, aprenderemos como usar o Dagger2 em um aplicativo multi-módulo e consideraremos o Dagger Android Injector.