Ответ 1
Укладка ListPreference
из XML напрямую не возможна. Проблема в том, что ListPreference
(через DialogPreference
) вызывает AlertDialog.Builder(Context)
, чтобы построить его Dialog
, а не AlertDialog.Builder(Context context, int themeResourceId)
. В то время как последний позволяет предоставить тему, первый не делает этого, заставляя его вернуться к теме Android по умолчанию.
Для проекта мне понадобился ListPreference
с настраиваемым цветом заголовка, настраиваемым стилем радиообмена и настраиваемым ListView-селектором (в основном, Holo в другом цвете). Я решил это, расширив ListPreference
и переопределив onPrepareDialogBuilder(Builder)
и OnCreateDialogView()
, чтобы я мог использовать пользовательский ListView с простым ArrayAdapter, а не Dialog
встроенный ListView
(который не поддерживает стилизацию), Мне также пришлось переопределить onDialogClosed()
, чтобы установить правильное значение для предпочтения.
Чтобы использовать его, все, что вам нужно сделать, это заменить имя класса предпочтения в ваших предпочтениях. xml rom ListPreference
до com.your.packagename.ThemedListPreference
. Кроме того, реализация идентична ListPreference.
public class ThemedListPreference extends ListPreference implements OnItemClickListener {
public static final String TAG = "ThemedListPreference";
private int mClickedDialogEntryIndex;
private CharSequence mDialogTitle;
public ThemedListPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ThemedListPreference(Context context) {
super(context);
}
@Override
protected View onCreateDialogView() {
// inflate custom layout with custom title & listview
View view = View.inflate(getContext(), R.layout.dialog_settings_updatetime, null);
mDialogTitle = getDialogTitle();
if(mDialogTitle == null) mDialogTitle = getTitle();
((TextView) view.findViewById(R.id.dialog_title)).setText(mDialogTitle);
ListView list = (ListView) view.findViewById(android.R.id.list);
// note the layout we're providing for the ListView entries
ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>(
getContext(), R.layout.btn_radio,
getEntries());
list.setAdapter(adapter);
list.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
list.setItemChecked(findIndexOfValue(getValue()), true);
list.setOnItemClickListener(this);
return view;
}
@Override
protected void onPrepareDialogBuilder(Builder builder) {
// adapted from ListPreference
if (getEntries() == null || getEntryValues() == null) {
// throws exception
super.onPrepareDialogBuilder(builder);
return;
}
mClickedDialogEntryIndex = findIndexOfValue(getValue());
// .setTitle(null) to prevent default (blue)
// title+divider from showing up
builder.setTitle(null);
builder.setPositiveButton(null, null);
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
mClickedDialogEntryIndex = position;
ThemedListPreference.this.onClick(getDialog(), DialogInterface.BUTTON_POSITIVE);
getDialog().dismiss();
}
@Override
protected void onDialogClosed(boolean positiveResult) {
// adapted from ListPreference
super.onDialogClosed(positiveResult);
if (positiveResult && mClickedDialogEntryIndex >= 0
&& getEntryValues() != null) {
String value = getEntryValues()[mClickedDialogEntryIndex]
.toString();
if (callChangeListener(value)) {
setValue(value);
}
}
}
}
Для моих элементов ListView я использовал макет ниже. Обратите внимание, что drawable/btn_radio_holo_light является XML-drawable, подобным тому, который находится в вашей папке android-sdk/platform/android-x/data/res/drawable, только со ссылками на разные чертежи.
<?xml version="1.0" encoding="utf-8"?>
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:checkMark="@drawable/btn_radio_holo_light"
android:gravity="center_vertical"
android:minHeight="@dimen/list_item_minheight"
android:paddingLeft="@dimen/list_item_paddingLeft"
android:paddingRight="@dimen/list_item_paddingLeft" />
В моем макете диалога (OnCreateDialogView()
) я использовал следующее:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/dialog_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:textColor="@color/title_color"
android:textSize="22sp" />
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="@color/divider_color" />
<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:listSelector="@drawable/list_selector" />
</LinearLayout>