пятница, 26 октября 2012 г.

PreferenceActivity: Простое решение для настроек в Android-приложении

Итак, вы потратили пару недель и массу усилий, чтобы сделать своё Android-приложение. Пора бы уже и публиковать, но тут вспоминаем что не хватает одной мелочи: клиенту негде редактировать свои настройки. Верстать ещё одну форму? Не хочется, заказчик забыл согласовать дизайн да и сроки уже поджимают. Вот бы сделать что-то стандартное, простое с минимумом кода! И ведь это вполне возможно. Просто берём и используем PreferenceActivity.

1. Вот оно, PreferenceActivity:

import android.os.Bundle;
import android.preference.PreferenceActivity;
 
public class PrefsActivity extends PreferenceActivity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.prefs);
    }
}

Совсем просто, не правда ли? Конечно, вся простота опирается на хитрую xml-разметку в файле res/xml/prefs.xml:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
    <PreferenceCategory
            android:summary="Username and password information"
            android:title="Login information" >
        <EditTextPreference
                android:key="username"
                android:summary="Please enter your login username"
                android:title="Username" />
        <EditTextPreference
                android:key="password"
                android:summary="Enter your password"
                android:title="Password" />
    </PreferenceCategory>
 
    <PreferenceCategory
            android:summary="Login and UI settings"
            android:title="Settings" >
        <CheckBoxPreference
                android:key="checkBox"
                android:summary="On/Off"
                android:title="Keep me logged in" />
 
        <ListPreference
                android:entries="@array/listOptions"
                android:entryValues="@array/listValues"
                android:key="listpref"
                android:summary="Role"
                android:title="You role" />
    </PreferenceCategory>
</PreferenceScreen>

Тут описаны три элемента для ввода данных в двух категориях. Два EditTextPreference, CheckBoxPreference и ListPreference. Первые по клику пользователя покажут поля для ввода, второй и третий соответственно галочку и список. Для списка нужно описать варианты для выбора. Это делаем в файле res/values/array.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="listOptions">
        <item>Customer</item>
        <item>Freelancer</item>
        <item>Manager</item>
    </string-array>
 
    <string-array name="listValues">
        <item>You are customer</item>
        <item>You are freelancer</item>
        <item>You are manager</item>
    </string-array>
</resources>

Два массива содержат соответственно то что увидит пользователь в списке выбора и то, что запишется в настройки. А в какие ключи SharedPreferences будут сохранены данные, спросите вы? Присмотритесь-ка к первому из xml приведённых тут. У каждого элемента есть атрибут android:key. Это и есть тот ключ, в который система сохранит настройки. Заметьте, без всякого нашего участия.

2. Наслаждаемся результатом:

Теперь сделаем главное Activity приложения, откуда будет вызываться окно настроек и куда мы выведем сохранённые настройки, чтобы проверить результат:

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
 
public class MyActivity extends Activity {
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
 
    public void setPrefs(View v) {
        Intent intent = new Intent(this, PrefsActivity.class);
        startActivity(intent);
    }
 
    public void showPrefs(View v) {
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
        String username = prefs.getString("username", "Anonymous");
        String passw = prefs.getString("password", "Not set");
        boolean checkBox = prefs.getBoolean("checkBox", false);
        String listPrefs = prefs.getString("listpref", "Not set");
        StringBuilder builder = new StringBuilder();
        builder.append("Username: " + username + "n");
        builder.append("Password: " + passw + "n");
        builder.append("Keep me logged in: " + String.valueOf(checkBox) + "n");
        builder.append("Role: " + listPrefs);
        ((TextView) findViewById(R.id.prefs)).setText(builder.toString());
    }
}

Разметка для него:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:orientation="vertical" android:gravity="center_horizontal" android:paddingTop="30dp">
 
    <Button
            android:id="@+id/btnSetPrefs"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Edit Preferences" android:onClick="setPrefs"/>
 
    <Button
            android:id="@+id/btnShowPreferences"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Display preferences" android:onClick="showPrefs"/>
 
    <TextView
            android:id="@+id/prefs"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
 
</LinearLayout>

И результат, после перехода к настройкам, ввода их, возврата и нажатия на кнопку Display preferences: