Przełączanie themes w android

Data publikacji: 2012-08-03 , Wyświetleń: 1538

fade animZmiana tematu (theme) w naszej aplikacji jest fajnym sposobem na uatrakcyjnienie jej wyglądu. Każdy użytkownik może mieć indywidualne preferencje co do kolorystyki czy układu. Najlepiej było by też aby dało zrobić się to z automatu paroma linijkami kodu. Poniżej opisze jeden ze sposobów w jaki można tego dokonać. 

 

Gdzie trzymać informacje o Theme?

Tutaj mamy tak naprawdę dowolność. Czy to będzie SharedPreference, zmienna statyczna czy baza danych nie ma to do końca znaczenia. Ja wybrałem na przykład klase Application. Daje nam to łatwy dostep do niej z każdego miejsca w kodzie co jest przydatne. Poniżej kod:

package com.example.theme.test;

import android.app.Application;

public class MyApp extends Application {
	
	private int baseTheme = R.style.AppTheme;
	
	@Override
	public void onCreate() {
		super.onCreate();
	}

	public int getBaseTheme() {
		return baseTheme;
	}

	public void setBaseTheme(int baseTheme) {
		this.baseTheme = baseTheme;
	}

}

Należy pamiętać o dodaniu linijki w AndroidManifext.xml:

...

Zapisanie i pobranie Theme:

// zapis info
((MyApp)getApplication()).setBaseTheme(R.style.AppTheme);
//...
// pobranie info i ustawienie tematu activity
setTheme(((MyApp)getApplication()).getBaseTheme());
//

 

Definiowanie atrybutów wyglądu

Ważnym elementem jest zdefiniowanie listy atrybutów które posłużą nam do zmiany wyglądu. Robimy to w pliku /res/values/attrs.xml Przykładowe atrybuty:

<?xml version="1.0" encoding="UTF-8"?>
<resources>
    <attr name="label.color" format="color" />
    <attr name="label.padding" />
    <attr name="label_gradient_start" format="color" />
    <attr name="label_gradient_end" format="color" />
    <attr name="label.gradient" />
</resources>

Każdy z nich posłuży do opisu innej własności obiektu.

Rzecz najważniejsza - definicja stylu (Theme)

W pliku /res/values/styles.xml definujemy klasy styli. Poniżej przykład:

<resources xmlns:android="http://schemas.android.com/apk/res/android">
    <style name="AppTheme" parent="android:Theme.Light.NoTitleBar">
		<item name="label.color">#FF0000</item>
		<item name="label.padding">20dp</item>
		<item name="label_gradient_start">#FF0000</item>
		<item name="label_gradient_end">#FFFFFF</item>
    </style>
    <style name="AppTheme2" parent="android:Theme.Light.NoTitleBar">
		<item name="label.color">#0000FF</item>
		<item name="label_gradient">#0000FF</item>
		<item name="label_gradient_start">#0000FF</item>
		<item name="label_gradient_end">#FFFFFF</item>
    </style>
</resources>

Mamy już 2 Themes. Czas na poukładanie XML'a naszego activity.

 

Wygląd Activity

Poniżej przykładowy kod wyglądu activity:

<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="20dp"
        android:layout_marginTop="24dp"
        android:text="Text label"
        android:textColor="?label.color"
        android:padding="?label.padding"
        android:background="@drawable/grad_bg"/>

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/textView1"
        android:layout_below="@+id/textView1"
        android:layout_marginTop="30dp"
        android:text="Button" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/button1"
        android:layout_centerHorizontal="true"
        android:text="  Button long  " />

    <EditText
        android:id="@+id/editText1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/button1"
        android:layout_below="@+id/button1"
        android:layout_marginTop="51dp"
        android:ems="10" 
        android:text="edit text">
    </EditText>

</RelativeLayout>

Jak widać używane są tutaj wcześniej utworzone atrybuty których wartości mamy umieszczone w naszym Theme. Pod takie elementy jak ?label.color czy ?label.padding podstawione zostanie to co wpisaliśmy w definicji stylu.

 

Podsumowanie

Teraz wystarczy przed startem Activity wkleić kod opodiadający za ustawienie aktualnego Theme. Jka to zrobić opisane jest na samym poczatku. Nalezy pamiętać że Theme zaskoczy jeżeli ustawimy go przed wywyołaniem setContentView inaczej nic sie nie zmieni.

Prosto i fajnie ;-)

 

Link do przykładowego projektu - theme_test.zip

Tagi: android, theme