0 komentarzy

PreferenceActivity – Aktywność wyświetlająca ustawienia aplikacji

Sierpień 5, 2011 Activity Podstawowe komponenty Tutoriale

Aby ułatwić pracę podczas tworzenia okna ustawień naszej aplikacji, twórcy Androida dostarczyli klasę PreferenceActivity. Jest to Aktywność przystosowana do wyświetlania typowej listy preferencji. Posiada ona własny wygląd, przez co możemy skupić się jedynie na treści która ją wypełnia. Oprócz tego dostarcza ona szereg udogodnień, które skracają czas wykonania preferencji naszej aplikacji do niezbędnego minimum.

Przykładowa aplikacja

W dzisiejszym artykule stworzymy prosty przykład demonstrujący typowe okno ustawień.

Przygotowanie

W naszej aplikacji wyświetlimy przycisk, który uruchomi nowe okno i wyświetli w nim ustawienia aplikacji. Oto kod źródłowy głównej Aktywności:

package pl.froger.hello.preferencesactivity;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity {
    private Button btnOpenPreferences;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        btnOpenPreferences = (Button)findViewById(R.id.btnOpenPreferences);
        btnOpenPreferences.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				startPreferencesActivity();
			}
		});
    }

    private void startPreferencesActivity() {
        Intent intent = new Intent(MainActivity.this, MyPreferences.class);
        startActivity(intent);
    }
}

Następnie stworzymy nową klasę Aktywności dziedziczącą po PreferenceActivity:

public class MyPreferences extends PreferenceActivity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
	}
}

Należy pamiętać o dodaniu powyższej klasy do AndroidManifest.xml:

<activity android:name=".MyPreferences"></activity>

Layout PreferenceActivity

Plik odpowiedzialny za layout Aktywności PreferenceActivity jest nieco inny od tego, którym definiujemy wygląd „normalnej” Aktywności. Przede wszystkim zapisuje się go w /res/xml/<nazwa_pliku>.xml.

Oprócz tego nie definiuje on stricte wyglądu preferencji, a jedynie elementy jakie tam występują. Oto lista pól, z jakich możemy skorzystać podczas tworzenia okna ustawień:

  • PreferenceScreen - jest to zarówno element-ojciec (jeżeli jest rootem w naszym pliku), jak i przycisk otwierający kolejne okno z elementami ustawień, które zawiera wewnątrz siebie (jeżeli nie jest rootem).
  • PreferenceCategory - służy do tego by uporządkować elementy ustawień, przechowując je w niewidocznym kontenerze z widocznym nagłówkiem.
  • Preference - element służący do ustawień typu „Custom” – działa jak zwykły przycisk, który należy oprogramować by robił coś konkretnego (np. „Przywróć ustawienia domyślne”).
  • CheckBoxPreference - element z checkboxem.
  • EditTextPreference - element, który po kliknięciu wyświetla okno dialogowe z polem EditText, w które możemy coś wpisać.
  • ListPreference - element wyświetlający okno dialogowe z listą radiobuttonów (elementów, spośród którym zaznaczyć można tylko jeden)
  • RingtonePreference - jest czymś podobnym do ListPreference, ale przystosowanym do wyświetlania listy dzwonków, jakie możemy ustawić w naszej aplikacji.

Ważniejszymi atrybutami powyższych pól są m.in.:

  • android:key – klucz pola. To za jego pomocą będziemy pobierać wartość zapisaną w konkretnym elemencie. Jest to też identyfikator elementu (odpowiednik android:id)
  • android:title – tytuł pola. W elemencie PreferenceCategory jest to tekst wyświetlany w belce.
  • android:summary – dodatkowy opis znajdujący się pod tytułem pola.
  • android:defaultValue – domyślna wartość pola.

Oto kompletny kod layoutu prezentujący większość powyższych elementów, z którego skorzystamy w naszej aplikacji:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
	<PreferenceCategory android:title="First preferences category">
		<CheckBoxPreference
			android:defaultValue="false"
			android:summary="Checkbox field"
			android:key="checkbox"
			android:title="Checkbox" />
		<EditTextPreference
			android:dialogTitle="Dialog title"
			android:key="edittext"
			android:summary="EditText field"
			android:positiveButtonText="OK"
			android:negativeButtonText="Cancel"
			android:dialogMessage="Dialog text content"
			android:title="EditText" />
	</PreferenceCategory>
	<PreferenceCategory android:title="Second preferences category">
		<ListPreference
			android:key="list"
			android:dialogTitle="Dialog title"
			android:title="ListPreference"
			android:entries="@array/list_options"
			android:entryValues="@array/list_values_options"
			android:summary="Pole typu ListPreference" />
	</PreferenceCategory>
	<PreferenceScreen
		android:key="prefScreen"
		android:title="PreferenceScreen"
		android:summary="Next preference screen">
		<Preference
			android:key="preference"
			android:title="Preference"
			android:summary="Preference field" />
	</PreferenceScreen>
</PreferenceScreen>

Przejdziemy teraz do kodu nasze Aktywności.

Kod źródłowy Aktywności z ustawieniami

W Aktywności preferencji, do zapamiętywania ustawień wykorzystamy SharedPreferences, które jest przeznaczone właśnie do tego zadania. Opis działania tego mechanizmu można znaleźć w tym artykule.

Zaczniemy od zdefiniowania stałych wykorzystywanych przy operacjach na SharedPreferences oraz pól naszego layoutu:

public class MyPreferences extends PreferenceActivity {
	private static final String PREFERENCES_NAME = "Preferences";
	private static final String CHECKBOX_FIELD = "checkbox";
	private static final String EDITTEXT_FIELD = "edittext";
	private static final String LIST_FIELD = "list";

	private SharedPreferences preferences;
	private CheckBoxPreference checkBoxPreference;
	private EditTextPreference editTextPreference;
	private ListPreference listPreference;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
	}
}

Teraz zajmiemy się inicjalizacją layoutu, poszczególnych pól oraz obiektu preferences w metodzie onCreate():

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		addPreferencesFromResource(R.xml.preferences);
		preferences = getSharedPreferences(PREFERENCES_NAME, Activity.MODE_PRIVATE);
		checkBoxPreference = (CheckBoxPreference) findPreference("checkbox");
		editTextPreference = (EditTextPreference) findPreference("edittext");
		listPreference = (ListPreference) findPreference("list");
		initPreferences();
	}

Jak widać jest kilka różnic w stosunku do operacji przeprowadzanych w typowej Aktywności:

  • Podpięcie layoutu wykonuje się za pomocą operacji addPreferencesFromResrource(int resId),
  • Adres poszczególnych pól layoutu pobieramy za pomocą metody findPreference(CharSequence key), które argumentem jest klucz zapisany pod atrybutem android:key w poszczególnych elementach layoutu.

Odczyt ustawień jest już typową operacją przeprowadzaną za pomocą SharedPreferences:

	private void initPreferences() {
		boolean checkBoxValue = preferences.getBoolean(CHECKBOX_FIELD, false);
		String editTextValue = preferences.getString(EDITTEXT_FIELD, "");
		String listDefaultValue = listPreference.getEntryValues()[0].toString();
		String listValue = preferences.getString(LIST_FIELD, listDefaultValue);
		checkBoxPreference.setChecked(checkBoxValue);
		editTextPreference.setText(editTextValue);
		listPreference.setValue(listValue);
	}

Podobnie wygląda zapis, który przeprowadzany jest w metodzie onPause(), czyli w każdym momencie, kiedy Aktywność preferencji przestaje być widoczna na ekranie urządzenia:

	@Override
	protected void onPause() {
		super.onPause();
		savePreferences();
	}

	private void savePreferences() {
		SharedPreferences.Editor editor = preferences.edit();
		editor.putBoolean(CHECKBOX_FIELD, checkBoxPreference.isChecked());
		editor.putString(EDITTEXT_FIELD, editTextPreference.getText());
		editor.putString(LIST_FIELD, listPreference.getValue());
		editor.commit();
	}

I to wszystko jeżeli chodzi o naszą Aktywność wyświetlającą ustawienia aplikacji.

Zrzuty ekranu

Kompletny kod źródłowy

Cały projekt dostępny jest na naszym githubie – HelloPreferencesActivity.

preferences.xml

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
	<PreferenceCategory android:title="First preferences category">
		<CheckBoxPreference
			android:defaultValue="false"
			android:summary="Checkbox field"
			android:key="checkbox"
			android:title="Checkbox" />
		<EditTextPreference
			android:dialogTitle="Dialog title"
			android:key="edittext"
			android:summary="EditText field"
			android:positiveButtonText="OK"
			android:negativeButtonText="Cancel"
			android:dialogMessage="Dialog text content"
			android:title="EditText" />
	</PreferenceCategory>
	<PreferenceCategory android:title="Second preferences category">
		<ListPreference
			android:key="list"
			android:dialogTitle="Dialog title"
			android:title="ListPreference"
			android:entries="@array/list_options"
			android:entryValues="@array/list_values_options"
			android:summary="Pole typu ListPreference" />
	</PreferenceCategory>
	<PreferenceScreen
		android:key="prefScreen"
		android:title="PreferenceScreen"
		android:summary="Next preference screen">
		<Preference
			android:key="preference"
			android:title="Preference"
			android:summary="Preference field" />
	</PreferenceScreen>
</PreferenceScreen>

MyPreferences.java

package pl.froger.hello.preferencesactivity;

import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.EditTextPreference;
import android.preference.ListPreference;
import android.preference.PreferenceActivity;

public class MyPreferences extends PreferenceActivity {
	private static final String PREFERENCES_NAME = "Preferences";
	private static final String CHECKBOX_FIELD = "checkbox";
	private static final String EDITTEXT_FIELD = "edittext";
	private static final String LIST_FIELD = "list";

	private SharedPreferences preferences;
	private CheckBoxPreference checkBoxPreference;
	private EditTextPreference editTextPreference;
	private ListPreference listPreference;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		addPreferencesFromResource(R.xml.preferences);
		preferences = getSharedPreferences(PREFERENCES_NAME, Activity.MODE_PRIVATE);
		checkBoxPreference = (CheckBoxPreference) findPreference("checkbox");
		editTextPreference = (EditTextPreference) findPreference("edittext");
		listPreference = (ListPreference) findPreference("list");
		initPreferences();
	}

	private void initPreferences() {
		boolean checkBoxValue = preferences.getBoolean(CHECKBOX_FIELD, false);
		String editTextValue = preferences.getString(EDITTEXT_FIELD, "");
		String listDefaultValue = listPreference.getEntryValues()[0].toString();
		String listValue = preferences.getString(LIST_FIELD, listDefaultValue);
		checkBoxPreference.setChecked(checkBoxValue);
		editTextPreference.setText(editTextValue);
		listPreference.setValue(listValue);
	}

	@Override
	protected void onPause() {
		super.onPause();
		savePreferences();
	}

	private void savePreferences() {
		SharedPreferences.Editor editor = preferences.edit();
		editor.putBoolean(CHECKBOX_FIELD, checkBoxPreference.isChecked());
		editor.putString(EDITTEXT_FIELD, editTextPreference.getText());
		editor.putString(LIST_FIELD, listPreference.getValue());
		editor.commit();
	}
}

Komentarze (0) Subskrybuj

Prześlij komentarz

Zaloguj się lub skorzystaj z profilu:

[rpxlogin redirect="http://www.android4devs.pl" prompt="" style="large"]

Możesz również zostawić komentarz bez rejestracji, korzystając z poniższego formularza:

Musisz być zalogowany aby móc pisać komentarze.