Ustawianie stylów globalnych dla widoków w systemie Android

125

Powiedzmy, że chcę mieć wszystkie TextViewwystąpienia w mojej aplikacji textColor="#ffffff". Czy istnieje sposób, aby ustawić to w jednym miejscu, zamiast ustawiać to dla każdego TextView?

Emanuil Rusev
źródło
1
Zaktualizowałem moje pytanie, aby było bardziej kompletne.
Cristian
Robię coś podobnego TUTAJ !!! stackoverflow.com/questions/17103894/…
toobsco42

Odpowiedzi:

250

Właściwie możesz ustawić domyślny styl dla TextViews (i większości innych wbudowanych widżetów) bez konieczności tworzenia niestandardowej klasy Java lub ustawiania stylu indywidualnie.

Jeśli spojrzysz themes.xmlna źródło Androida, zobaczysz kilka atrybutów domyślnego stylu dla różnych widżetów. Kluczem jest atrybut textViewStyle(lub editTextStyleitp.), Który można zastąpić w kompozycji niestandardowej. Możesz to zmienić w następujący sposób:

Utwórz 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>

Następnie po prostu zastosuj ten motyw do swojej aplikacji w AndroidManifest.xml:

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

Wszystkie widoki tekstu będą domyślnie miały styl zdefiniowany w MyTextViewStyle(w tym przypadku pogrubiony i czerwony)!

Zostało to przetestowane na urządzeniach od poziomu API 4 i wydaje się, że działa świetnie.

Steve Pomeroy
źródło
1
Najbardziej eleganckie rozwiązanie, jakie do tej pory widziałem.
Italo Borssatto
@Steve, jeśli dołączę element <item name="android:textViewStyle">@style/MyTextViewStyle</item>do stylu MyTheme, a następnie zastosuję styl do mojej aplikacji, wszystkie moje TextViews będą wyświetlane zgodnie ze stylem (nawet nazwa aplikacji na pasku akcji). Jak rozwiązać ten problem za pomocą paska akcji? Chcę, żeby miał domyślny wygląd. Github
Maksim Dmitriev
@Steve, Jak zastosować motyw zarówno (paska akcji, jak i widżetu) w aplikacji
Pratik Butani
Nie jestem pewien, jak odróżnić ActionBar od innych rzeczy. Możesz znaleźć miejsce, w którym ustawiono styl ActionBar, a następnie umieścić je <item name="android:textViewStyle">@style/MyTextViewStyle</item>tam, po prostu wskazując na domyślny ActionBar (lub coś podobnego)
Steve Pomeroy,
@StevePomeroy to nie działa dla mnie ... czy możesz zapewnić wsparcie. Mój styl dla TextViews pozostaje taki sam. Czy istnieje minimum elementów, które muszę ustawić, czy też są elementy, których nie mogę ustawić?
Mike
52

Można to zrobić na dwa sposoby:

1. Używanie stylów

Możesz zdefiniować własne style, tworząc pliki XML w res/valueskatalogu. Załóżmy więc, że chcesz mieć czerwony i pogrubiony tekst, a następnie utwórz plik z następującą zawartością:

<?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>

Możesz na przykład nazwać go tak, jak chcesz res/values/red.xml. Następnie jedyne, co musisz zrobić, to użyć tego widoku w wybranych widżetach, na przykład:

<?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>

Więcej informacji znajdziesz w tym artykule: Zrozumienie motywów i stylów Androida

2. Korzystanie z klas niestandardowych

Jest to kolejny możliwy sposób osiągnięcia tego celu i polegałby na zapewnieniu własnego, TextViewktóry ustawiałby kolor tekstu zawsze na taki, jaki chcesz; na przykład:

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);
    }
}

Następnie musisz po prostu traktować to jako normalne TextVieww swoim pliku 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>

To, czy wybierzesz jeden, czy inny wybór, zależy od Twoich potrzeb. Jeśli jedyną rzeczą, którą chcesz zrobić, jest modyfikacja wyglądu, najlepszym podejściem jest pierwsze. Z drugiej strony, jeśli chcesz zmienić wygląd i dodać nowe funkcje do swoich widżetów, druga jest do zrobienia.

Cristian
źródło
Używanie klas niestandardowych powinno być preferowane, ponieważ jest to czystsze podejście i pomaga zachować niewielką wagę pliku xml.
Amit Kumar
@AmitKumar Nie, nie powinni! W tym konkretnym przypadku oznaczałoby to użycie oddzielnej klasy niestandardowej dla każdej wartości atrybutu. To generuje dużo nadmiarowego kodu i sprawia, że ​​rzeczywisty układ nie jest już czytelny (będziesz musiał odwiedzić każdą klasę, aby zobaczyć, co robi, zamiast po prostu czytać kilka wierszy xml). Klasy niestandardowe powinny być używane tylko wtedy, gdy modyfikujesz zachowanie, ale nie wtedy, gdy jedyną zmianą jest wygląd widoku.
Andre
Czy nie można ustawić stylu widoku niestandardowego z XML? Dlaczego nie możemy go użyć w custom_view_layout.xmlpliku używanym do nadmuchania klasy niestandardowej?
lucidbrot
5

Aby uzyskać domyślny kolor tekstu w TextView, ustaw android:textColorTertiaryw motywie żądany kolor:

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

Wiele innych kolorów kontrolek systemu Android można kontrolować za pomocą atrybutów struktury lub obsługi atrybutów biblioteki, jeśli używasz biblioteki obsługi.

Aby uzyskać listę atrybutów, które można wybierać, sprawdź kod źródłowy Androida z styles.xmli themes.xmlczy to bardzo pomocne Istota Dan Lew, spróbuj zmienić każdą wartość i zobaczyć, co zmieni się na ekranie.

hidro
źródło
Dziękuje! Spędziłem sporo czasu, zastanawiając się, dlaczego textColorPrimary nie działa.
pratt
3

Zdefiniuj styl i użyj go na każdym widżecie, zdefiniuj motyw, który zastępuje domyślne ustawienie Androida dla tego widżetu lub zdefiniuj zasób ciągu i odwołuj się do niego w każdym widżecie

TWH
źródło