如何自定义列表首选项单选按钮

时间:2012-05-05 09:55:30

标签: android radio-button customization listpreference

我已经在我的应用程序中自定义了所有的radioButtons,但listPreference中的radioButtons没有自定义。

我使用过这个名为btn_radio.xml的xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:state_window_focused="false"
      android:drawable="@drawable/radio_selected" />
<item android:state_checked="false" android:state_window_focused="false"
      android:drawable="@drawable/radio_unselected" />

<item android:state_checked="true" android:state_pressed="true"
      android:drawable="@drawable/radio_selected" />
<item android:state_checked="false" android:state_pressed="true"
      android:drawable="@drawable/radio_unselected" />

<item android:state_checked="true" android:state_focused="true"
      android:drawable="@drawable/radio_selected" />
<item android:state_checked="false" android:state_focused="true"
      android:drawable="@drawable/radio_unselected" />

<item android:state_checked="false" android:drawable="@drawable/radio_unselected" />
<item android:state_checked="true" android:drawable="@drawable/radio_selected" />
</selector>

这是customRadioButton,它扩展了android自定义单选按钮

<style name="CustomRadioButton"    Parent="@android:style/Widget.CompoundButton.RadioButton">
    <item name="android:button">@drawable/btn_radio</item>
</style>

在我的应用程序的主题中我做了这个改变

<item name="android:radioButtonStyle">@style/CustomRadioButton</item>
    <item name="android:listChoiceIndicatorSingle">@style/CustomRadioButton</item>

此更改会自定义我的应用中的所有radioButtons,但ListPreference中的radioButtons

2 个答案:

答案 0 :(得分:26)

不能直接从XML设置ListPreference样式。问题是ListPreference(通过DialogPreference)调用AlertDialog.Builder(Context)来构建其Dialog,而不是AlertDialog.Builder(Context context, int themeResourceId)。虽然后者允许提供主题,但前者没有,导致它回退到默认的Android主题。

对于一个项目,我需要一个带有自定义标题颜色的ListPreference,一个自定义单选按钮样式和一个自定义ListView选择器(基本上是不同颜色的Holo)。我通过扩展ListPreference并覆盖onPrepareDialogBuilder(Builder)OnCreateDialogView()解决了这个问题,因此我可以使用带有简单ArrayAdapter的自定义ListView,而不是Dialog的内置{{1} (不支持样式)。我还必须覆盖ListView才能为首选项设置正确的值。

要使用它,您只需将您的preferences.xml rom onDialogClosed()中的首选项的类名替换为ListPreference即可。除此之外,实现与ListPreference相同。

com.your.packagename.ThemedListPreference

对于我的ListView项目,我使用了下面的布局。请注意,drawable / btn_radio_holo_light是一个XML-drawable,类似于android-sdk / platforms / android-x / data / res / drawable文件夹中的那个,只能引用不同的drawables。

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);
            }
        }
    }
}

对于我的对话框布局(<?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()

答案 1 :(得分:0)

请看我的回答 here,也许有帮助。

这是一种更容易解决问题的方法。