В андроиде существует мощный фреймворк для работы с настройками приложения. Как говорит http://developer.android.com, надо стремиться к использованию оного, дабы пользователь мог контролировать приложение стандартным способом, а не конфузиться в интерфейсе уникальном и непознанном :-) Для настроек, значения которых описываются простыми типами (будь то строки, буль или число), Preference API справляеться "на ура", однако в жизни часто так бывает, что для всеобъемлющего счастья нехватает самую малость - чуть больше, чем есть сейчас :) Итак, сегодня поговорим о том как организовать интерфейс для сохранения более комплексных сущностей. Предположим, мы создаём некое клиентское приложение, в настройках которого надо реализовать возможность ввести адрес вебсервиса. Как известно - веб-адрес имеет следующую структуру:
Символьное_Имя_или_IP_адрес[:Порт(не обязательно)]
Отсюда следует, что у нас настройка "адрес" будет состоять из двух частей - собсно адреса и порта.
Итак, начнём...1.UI Первым делом надо продумать пользовательский интерфейс под это дело. Благо - в нашем случае всё довольно просто. Должно получиться что-то такое:
Не будем претендовать на сверхоптимальный UI, напишем следующее:
<?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="wrap_content"
android:gravity="center"
android:layout_gravity="center"
android:layout_margin="10dp"
android:padding="10dp">
<LinearLayout android:orientation="horizontal"
android:layout_height="wrap_content"
android:layout_width="fill_parent">
<TextView android:text="@string/preferences_webservice_address"
android:id="@+id/preference_webservice_address_legend"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:layout_gravity="right"
style="@style/RegularLightLabel"/>
<EditText android:id="@id/preference_webservice_address"
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="wrap_content"
android:lines="1" />
</LinearLayout>
<LinearLayout android:orientation="horizontal"
android:layout_height="wrap_content"
android:layout_width="fill_parent">
<TextView android:id="@+id/preference_webservice_port_legend"
android:text="@string/preferences_webservice_port"
android:layout_gravity="right"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
style="@style/RegularLightLabel" />
<EditText
android:id="@id/preference_webservice_port"
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="wrap_content"/>
</LinearLayout>"
</LinearLayout>
2. Класс диалога. Теперь нам необходимо написать класс, унаследованый от DialogPreference, который будет отображать наш диалог настроек. Некоторые нюансы: - необходимо в перегруженом методе onClick загрузить наш UI из xml-файла:
public WebServicePreferences(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
setDialogLayoutResource(R.layout.preferences_network);
}
- желательно в перегруженом onCreateDialogView сохранить в локальных переменных елементы управления диалога - проще потом будет выцарапать из них модифицированые значения настроек:
@Override
protected View onCreateDialogView() {
View root = super.onCreateDialogView(); //создать диалог и вернуть корневой елемент
pref_address = (EditText)root.findViewById(R.id.preference_webservice_address);
pref_port = (EditText)root.findViewById(R.id.preference_webservice_port);
return root;
}
- не забываем создать методы-аксесоры для значений настроек - чтобы можно было внести/выдрать значения извне.
- перегружаем метод onClick, в котором сохраняем значения в локальных переменных и вызываем слушатель измененний(если нажата кнопка Окей):
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case Dialog.BUTTON_POSITIVE: //Тыцнули кнопку Ок.Читаем значения в переменные
pref_address_value = pref_address.getText().toString();
pref_port_value = pref_port.getText().toString();
//вызываем слушатель
callChangeListener(null);
break;
case Dialog.BUTTON_NEUTRAL:
//... если вдруг...
break;
case Dialog.BUTTON_NEGATIVE:
//... пользователь сказал "не-а..."
break;
default: //этого никогда не произойдёт, но всё же вызываем родительскую реализацию...
super.onClick(dialog, which);
break;
}
}
switch (which) {
case Dialog.BUTTON_POSITIVE: //Тыцнули кнопку Ок.Читаем значения в переменные
pref_address_value = pref_address.getText().toString();
pref_port_value = pref_port.getText().toString();
//вызываем слушатель
callChangeListener(null);
break;
case Dialog.BUTTON_NEUTRAL:
//... если вдруг...
break;
case Dialog.BUTTON_NEGATIVE:
//... пользователь сказал "не-а..."
break;
default: //этого никогда не произойдёт, но всё же вызываем родительскую реализацию...
super.onClick(dialog, which);
break;
}
}
3. Явление настроек на данном этапе(а может быть, нам с этого этапа и следовало начинать) нам следует реализовать явление, унаследованое от PreferenceActivity, и написать графический интерфейс для него. Нюансы: - в onCreate, грузим наш интерфейс из xml:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
- реализовываем интерфейс OnPreferenceChangeListener (слушатель, который мы вызываем из onClick нашего диалога - как раз и описываеться этим интерфейсом)В результате получилось следующее:
которое, при нажатии на пункт Address, превращаеться в
а если написать какую-то пургу вместо адреса, увидим следующее:
Немає коментарів:
Дописати коментар