Кастомизация PreferenceActivity. Часть 2 – изменение фона ListPreference
В предыдущей публикации рассматривалась стилизация внешнего вида PreferenceActivity. В этой же статье я хочу рассказать о том, как можно изменить внешний вид ListPreference на свой собственный. Давайте приступим к работе.
Для начала, как отмечалось в предыдущей статье, нужно будет создать приложение с одним главным Activity, в котором будет находиться кнопка вызова PreferenceActivity. По традиции название класса для главного Activity останется неизменным – MainActivity, ну а PreferenceActivity я назову PrefsActivity. Убедитесь в том, что эти два Activity прописаны в манифесте. Подбробно рассматривать это процедуру я не буду, поскольку это было расписано в предыдущей статье. При этом следует обратить особое внимание на то, что ListPreference будет нами создаваться программно, поэтому в методе onCreate класса PrefsActivity следует оставить только эту строку super.onCreate(savedInstanceState);.
Теперь приступим к самому интересному – будем создавать свой ListPreference с кастомным фоном. Для начала нужно скачать текстуру для фона отсюда и поместить ее в папку res/drawable нашего проекта. Если такой папки не существует – ее нужно создать.
Для того, чтобы поменять внешний вид ListPreference, нужно создать свой собственный класс, который будет расширять функционал класса ListPreference. Я назову этот класс CustomListPreference. Пока что он будет содержать только два конструктора и иметь поле со ссылкой на LayoutInflater, необходимой для создания элементов списка и массива данных типа CharSequence (для чего он нужен я объясню позже), а также ссылку на Context для создания адаптера для списка. Вот как это будет выглядеть:
import android.content.Context;
import android.preference.ListPreference;
import android.util.AttributeSet;
import android.view.LayoutInflater;
public class CustomListPreference extends ListPreference {
private LayoutInflater mInflater;
private CharSequence[] entries;
private Context mContext;
public CustomListPreference(Context context) {
super(context);
mInflater = LayoutInflater.from(context);
mContext = context;
}
public CustomListPreference(Context ctxt, AttributeSet attrs) {
super(ctxt, attrs);
}
}
Теперь необходимо создать класс-адаптер для списка, в котором будем указывать, какой фон должен быть у его элементов. Для этого следует создать в CustomListPreference новый класс - назовем его CustomListAdapter,расширяющий класс BaseAdapter. Опускаю пример адаптера реализации паттерна ViewHolder. Но в рабочих приложениях, с целью повышения их быстродействия, Google настоятельно рекомендует этот паттерн использовать. Более детально об этом можно прочитать здесь.
Листинг класса CustomListAdapter:
private class CustomListAdapter extends BaseAdapter {
public CustomListAdapter(Context context) {
}
public int getCount() {
return entries.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position){
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
View row = convertView;
TextView tView;
if(row == null) {
row = mInflater.inflate(android.R.layout.simple_list_item_single_choice, parent, false);
tView = (TextView)row.findViewById(android.R.id.text1);
}
else tView = (TextView)row.findViewById(android.R.id.text1);
row.setBackgroundResource(R.drawable.background);
tView.setText(entries[position]);
return row;
}
}
В методе getView с помощью LayoutInflater-a мы создаем view-представление для элемента списка, после чего указываем ему, какой фон следует использовать и возвращаем наш кастомный элемент. Следует обратить внимание на то, что в текстовое поле передается значение из массива entries, который был объявлен ранее в качестве поля нашего класса. Что же это за массив? ListPreference должен содержать в себе два массива текстовых данных. Один массив содержит в себе «человекопонятные» текстовые данные. Они будут отображаться в качестве содержимого списка. Он то нам и нужен для того, чтобы задать текст для текстовых полей. В данный момент этот массив является нулевым и, соответственно, нам нужно его проинициализировать, а также назначить нашему списку адаптер. Для начала – следует добавить в класс CustomListPreference поле, ссылающееся на адаптер private CustomListAdapter mAdapter;
и переопределить несколько методов из класса ListPreference
Листинг этих методов:
@Override
protected void onPrepareDialogBuilder(Builder builder) {
entries = getEntries();
mAdapter = new CustomListAdapter(mContext);
builder.setAdapter(mAdapter, this);
builder.setNegativeButton(null, null);
super.onPrepareDialogBuilder(builder);
}
@Override
protected void onDialogClosed(boolean positiveResult) {
super.onDialogClosed(positiveResult);
setSummary(getSummary());
}
@Override
public CharSequence getSummary() {
try{
int pos = findIndexOfValue(getValue());
return getEntries()[pos];
}
catch(Exception e){return "";}
}
Все, на этом реализация класса CustomListPreference завершена и нам необходимо добавить его в окно настроек. Листинг класса CustomListPreference.
Теперь следует програмно создать список в PrefsActivity. Для начала нужно создать два массива с текстовыми данными для списка, затем в методе onCreate создать корневой экран для настроек, кастомизированный список, назначить списку текстовые данные и добавить его в экран настроек.
Листинг класса PrefsActivity:
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.preference.PreferenceScreen;
public class PrefsActivity extends PreferenceActivity {
private String [] entries = new String[]{"One", "Two", "Three"};
private String [] entryValues = new String [] {"one_key", "two_key", "three_key"};
@SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
PreferenceScreen rootScreen = getPreferenceManager().createPreferenceScreen(this);
setPreferenceScreen(rootScreen);
CustomListPreference list = new CustomListPreference(this);
list.setKey("list");
list.setTitle("List");
list.setSummary("Description of list");
list.setEntries(entries);
list.setEntryValues(entryValues);
rootScreen.addPreference(list);
}
}
Запускаем, проверяем. Все работает!
- 4168 просмотров