Definindo estilos globais para modos de exibição no Android

125

Digamos que eu queira que todas as TextViewinstâncias do meu aplicativo tenham textColor="#ffffff". Existe uma maneira de definir isso em um só lugar, em vez de defini-lo para cada um TextView?

Emanuil Rusev
fonte
1
Atualizei minha pergunta para que fique mais completa.
Cristian
Estou fazendo algo parecido AQUI !!! stackoverflow.com/questions/17103894/...
toobsco42

Respostas:

250

Na verdade, você pode definir um estilo padrão para o TextViews (e a maioria dos outros widgets internos) sem precisar fazer uma classe java personalizada ou definir o estilo individualmente.

Se você der uma olhada na themes.xmlfonte do Android, verá vários atributos para o estilo padrão de vários widgets. A chave é o atributo textViewStyle(ou editTextStyleetc.) que você substitui no seu tema personalizado. Você pode substituí-los da seguinte maneira:

Crie um styles.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="MyTheme" parent="android:Theme">
    <item name="android:textViewStyle">@style/MyTextViewStyle</item>
</style>

<style name="MyTextViewStyle" parent="android:Widget.TextView">
    <item name="android:textColor">#F00</item>
    <item name="android:textStyle">bold</item>
</style>
</resources>

Em seguida, basta aplicar esse tema ao seu aplicativo em AndroidManifest.xml:

<application […] android:theme="@style/MyTheme">

E todas as suas visualizações de texto serão padronizadas para o estilo definido em MyTextViewStyle(neste caso, negrito e vermelho)!

Isso foi testado em dispositivos da API nível 4 em diante e parece funcionar muito bem.

Steve Pomeroy
fonte
1
A solução mais elegante que vi até agora.
Italo Borssatto
@ Steve, se eu incluir o item <item name="android:textViewStyle">@style/MyTextViewStyle</item>no estilo MyTheme e depois aplicá-lo ao meu aplicativo, todos os meus TextViews serão mostrados de acordo com o estilo (até o nome do aplicativo na barra de ação). Como resolver o problema com a barra de ação? Eu quero que ele tenha a aparência padrão. Github
Maksim Dmitriev
@ Steve, Como aplicar ambos (barra de ação e widget) tema em aplicação
Pratik Butani
Não tenho certeza sobre como diferenciar a ActionBar de outras coisas. Você pode ser capaz de encontrar sempre o seu estilo ActionBar está definido e, em seguida, colocar <item name="android:textViewStyle">@style/MyTextViewStyle</item>lá também, apenas apontando para a ActionBar padrão (ou algo similar)
Steve Pomeroy
@StevePomeroy isso não funciona para mim .. você pode fornecer algum suporte. Meu estilo para as TextViews permanece o mesmo. Há um mínimo de itens que eu preciso definir ou existem alguns itens que não tenho permissão para definir?
1755 Mike
52

Existem duas maneiras de fazer isso:

1. Usando estilos

Você pode definir seus próprios estilos criando arquivos XML no res/valuesdiretório Então, suponhamos que você queira ter texto em vermelho e negrito e crie um arquivo com este conteúdo:

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <style name="MyRedTheme" parent="android:Theme.Light">
    <item name="android:textAppearance">@style/MyRedTextAppearance</item>
  </style>
  <style name="MyRedTextAppearance" parent="@android:style/TextAppearance">
    <item name="android:textColor">#F00</item>
    <item name="android:textStyle">bold</item>
  </style>
</resources>

Você pode nomear como quiser, por exemplo res/values/red.xml. Então, a única coisa que você precisa fazer é usar essa exibição nos widgets que você deseja, por exemplo:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView
    style="@style/MyRedTheme"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="This is red, isn't it?"
    />
</LinearLayout>

Para referência adicional, você pode ler este artigo: Entendendo os temas e estilos do Android

2. Usando Classes Customizadas

Essa é outra maneira possível de conseguir isso e seria fornecer a sua própria, TextViewque definiria sempre a cor do texto para o que você quiser; por exemplo:

import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.widget.TextView;
public class RedTextView extends TextView{
    public RedTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setTextColor(Color.RED);
    }
}

Então, você apenas precisa tratá-lo como normal TextViewno seu arquivo XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<org.example.RedTextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="This is red, isn't it?"
    />
</LinearLayout>

Se você usa uma ou outra opção, depende de suas necessidades. Se a única coisa que você deseja fazer é modificar a aparência, a melhor abordagem é a primeira. Por outro lado, se você quiser alterar a aparência e adicionar novas funcionalidades aos seus widgets, o segundo é o caminho a percorrer.

Cristian
fonte
o uso de classes personalizadas deve ser preferido, pois é uma abordagem mais limpa e ajuda a manter o peso do arquivo xml.
Amit Kumar #:
@AmitKumar Não, eles não deveriam! Nesse caso em particular, isso significaria usar uma classe personalizada separada para cada valor de atributo diferente. Isso produz muito código inchado e torna o layout real não mais legível (você terá que visitar cada classe para ver o que está fazendo, em vez de apenas ler algumas linhas xml). Classes personalizadas devem ser usadas apenas se você modificar o comportamento, mas não se a única alteração for a aparência da exibição.
Andre Andre
Não é possível definir o estilo de uma exibição personalizada do xml? Por que não podemos usá-lo no custom_view_layout.xmlarquivo usado para inflar uma classe personalizada?
lucidbrot 7/01
5

Para a cor padrão do texto TextView, defina android:textColorTertiaryno seu tema a cor desejada:

<item name="android:textColorTertiary">@color/your_text_color</item>

Muitas outras cores do controle Android podem ser controladas usando atributos da estrutura ou atributos da biblioteca de suporte, se você usar a biblioteca de suporte.

Para obter uma lista de atributos que pode definir, confira o código fonte do Android de styles.xmle themes.xml, ou esta muito útil essência por Dan Lew, tente alterar cada valor e ver o que eles mudam na tela.

hidro
fonte
Obrigado cara! Passei muito tempo descobrindo por que o textColorPrimary não funciona.
pratt
3

Defina um estilo e use-o em cada widget, defina um tema que substitua o padrão do Android para esse widget ou defina um recurso de sequência e faça referência a ele em cada widget

TWH
fonte