Android com.android.support:preference-v7庫(kù)的使用

以前使用android.preference包里面的類(lèi)創(chuàng)建出來(lái)的偏好設(shè)置界面是沒(méi)有兼容低版本的,后來(lái)發(fā)現(xiàn)com.android.support:preference庫(kù)有對(duì)低版本做兼容悲关,在低版本上面也可以有Material Design風(fēng)格袒哥,于是對(duì)其作了一番研究秕脓。

1、應(yīng)用的主題需要繼承自Theme.AppCompat系列:

<style name="AppBaseTheme" parent="Theme.AppCompat.Light.NoActionBar">
</style>

2、在build.gradle中添加以下依賴(lài):

compile 'com.android.support:preference-v7:26.1.0'
compile 'com.android.support:preference-v14:26.1.0'

3、在應(yīng)用的主題里面添加:

<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>

4侦另、編寫(xiě)my_pref.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    android:key="preference_screen_settings"
    android:title="settings">

    <android.support.v7.preference.PreferenceCategory android:title="Category">

        <android.support.v7.preference.SwitchPreferenceCompat
            android:defaultValue="true"
            android:key="key_1"
            android:summary="Summary"
            android:title="Title" />

        <android.support.v7.preference.EditTextPreference
            android:defaultValue="default_value"
            android:dialogMessage="dialog_message"
            android:key="key_2"
            android:summary="Summary"
            android:title="Title" />
        <android.support.v7.preference.CheckBoxPreference
            android:defaultValue="true"
            android:key="key_3"
            android:summary="Summary"
            android:title="Title" />

        <android.support.v7.preference.ListPreference
            android:defaultValue="2"
            android:entries="@array/list_preference_entries"
            android:entryValues="@array/list_preference_entry_values"
            android:key="key_4"
            android:summary="Summary"
            android:title="Title" />

        <android.support.v7.preference.SeekBarPreference
            android:defaultValue="20"
            android:key="key_5"
            android:max="1000"
            android:min="0"
            android:summary="Summary"
            android:title="Title" />
    </android.support.v7.preference.PreferenceCategory>

</android.support.v7.preference.PreferenceScreen>

5、編寫(xiě)承載偏好設(shè)置的Fragment尉共,這里繼承自PreferenceFragmentCompat類(lèi):

public class PreferenceFragment extends PreferenceFragmentCompat {
    @Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
        addPreferencesFromResource(R.xml.my_pref);
    }
}

效果圖:


Screenshot_20180711-221330.jpg

6褒傅、對(duì)Preference節(jié)點(diǎn)進(jìn)行刪除、添加和修改:

@Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
        addPreferencesFromResource(R.xml.my_pref);

        PreferenceCategory category = (PreferenceCategory) findPreference("category");
        category.removePreference(findPreference("key_3"));

        ListPreference listPreference = new ListPreference(getContext());
        listPreference.setEntries(new String[]{"A", "B", "C", "D"});
        listPreference.setEntryValues(new String[]{"A", "B", "C", "D"});
        listPreference.setSummary("Summary");
        listPreference.setTitle("Title");
        listPreference.setDialogTitle("DialogTitle");
        listPreference.setKey("key_6");
        listPreference.setDefaultValue("C");
        category.addPreference(listPreference);

        Preference preference1 = findPreference("key_1");
        preference1.setTitle("AAAAA");
    }

7袄友、修改某個(gè)Preference的點(diǎn)擊事件:

Preference preference2 = findPreference("key_2");
        preference2.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
            @Override
            public boolean onPreferenceClick(Preference preference) {
                //TODO
                return false;
            }
        });

8殿托、自定義ListPreference,可以自定義一個(gè)attrs剧蚣,從XML文件中把屬性值傳進(jìn)來(lái)支竹;重寫(xiě)onBindViewHolder方法可以通過(guò)holder拿到對(duì)應(yīng)的itemView,這樣便可以對(duì)itemView里面的內(nèi)容進(jìn)行修改鸠按,這里我的itemView是自定義的唾戚,布局通過(guò)android:layout="@layout/item_view"進(jìn)行設(shè)置:

public class MyListPreference extends ListPreference {

    private String titleText;

    public MyListPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyListPreference);
        titleText = typedArray.getString(R.styleable.MyListPreference_title_text);
        typedArray.recycle();
    }

    @Override
    public void onBindViewHolder(PreferenceViewHolder holder) {
        super.onBindViewHolder(holder);
        View view = holder.itemView;
        TextView tvTitle= (TextView) view.findViewById(R.id.tv_title_text);
        tvTitle.setText(titleText);
    }
}

9、對(duì)CheckBoxPreference和SwitchPreference的自定義類(lèi)似待诅,如果只想修改右邊的控件(將Switch修改成自定義的View)可以在對(duì)應(yīng)的Preference中添加android:widgetLayout="@layout/switch_layout",再自定義一個(gè)類(lèi)繼承自SwitchPreferenceCompat:

public class MySwitchPreferenceCompat extends SwitchPreferenceCompat {

    private AppCompatImageView imageView;

    public MySwitchPreferenceCompat(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    public MySwitchPreferenceCompat(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public MySwitchPreferenceCompat(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MySwitchPreferenceCompat(Context context) {
        super(context);
    }

    @Override
    public void onBindViewHolder(PreferenceViewHolder holder) {
        super.onBindViewHolder(holder);
        imageView = holder.itemView.findViewById(R.id.preference_img);
        setState(imageView);
    }

    @Override
    protected void onClick() {
        super.onClick();
        setState(imageView);
    }

    private void setState(AppCompatImageView appCompatImageView) {
        Drawable drawable = getContext().getResources().getDrawable(
                getSharedPreferences().getBoolean(getKey(), false) ?
                        R.drawable.ic_arrow_upward_black_24dp : R.drawable.ic_arrow_downward_black_24dp);
        appCompatImageView.setImageDrawable(drawable);
    }
}

10熊镣、在自定義EditTextPreference時(shí)總感覺(jué)很奇怪卑雁,不知道為什么默認(rèn)的EditTextPreference彈窗這么不好看(Google自己的規(guī)范上面都說(shuō)Dialog內(nèi)容到左右的邊距為24dp):
默認(rèn)的EditTextPreference


Screenshot_20180711-233306.jpg
public class MyEditTextPreference extends EditTextPreference {

    public MyEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    public MyEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public MyEditTextPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyEditTextPreference(Context context) {
        super(context);
    }

    @Override
    protected void onClick() {
        View view = LayoutInflater.from(getContext()).inflate(R.layout.dialog_rename_layout, null);
        final EditText editText = view.findViewById(R.id.rename_dialog_edit);
        editText.setHint("");
        editText.setText(getSharedPreferences().getString(getKey(), ""));
        editText.setSelectAllOnFocus(true);
        AlertDialog.Builder dialogBuild = new AlertDialog.Builder(getContext());
        AlertDialog renameDialog = dialogBuild.setTitle(R.string.main_rename)
                .setView(view)
                .setTitle(getTitle())
                .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        String string = editText.getText().toString().trim();
                        getSharedPreferences().edit().putString(getKey(), string).apply();
                        dialog.dismiss();
                    }
                }).setNegativeButton(R.string.cancel, null).show();
    }
}

11、如果有需求需要在MyEditTextPreference中拿到MainActivity的方法或變量绪囱,則需要在Fragment里面?zhèn)鬟M(jìn)來(lái)测蹲,在這里用getContext拿到的Context是ContextThemeWrapper,MainActivity mainActivity = (MainActivity) getContext();這樣強(qiáng)轉(zhuǎn)是會(huì)報(bào)錯(cuò)的鬼吵。

//Fragment中set進(jìn)來(lái)
MyEditTextPreference editTextPreference = (MyEditTextPreference) findPreference("key_8");
editTextPreference.setActivity(getActivity());

12扣甲、修改Preference的樣式:

<item name="colorAccent">@color/colorAccent</item>
<item name="android:textColorPrimary">#FFFF00FF</item>
<item name="android:textColorSecondary">#FF666666</item>
<item name="textColorAlertDialogListItem">#FF00FFFF</item>
Screenshot_20180713-213210.jpg

13、自定義EditTextPreference在低版本手機(jī)中碰到過(guò)選中文字背景顏色不是你設(shè)置的顏色的情況:

<item name="android:textColorHighlight">#FF0000FF</item>
a.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末齿椅,一起剝皮案震驚了整個(gè)濱河市琉挖,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌涣脚,老刑警劉巖示辈,帶你破解...
    沈念sama閱讀 212,222評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異遣蚀,居然都是意外死亡矾麻,警方通過(guò)查閱死者的電腦和手機(jī)纱耻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,455評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)险耀,“玉大人弄喘,你說(shuō)我怎么就攤上這事∷ξ” “怎么了蘑志?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,720評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)柴灯。 經(jīng)常有香客問(wèn)我卖漫,道長(zhǎng),這世上最難降的妖魔是什么赠群? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,568評(píng)論 1 284
  • 正文 為了忘掉前任羊始,我火速辦了婚禮,結(jié)果婚禮上查描,老公的妹妹穿的比我還像新娘突委。我一直安慰自己,他們只是感情好冬三,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,696評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布匀油。 她就那樣靜靜地躺著,像睡著了一般勾笆。 火紅的嫁衣襯著肌膚如雪敌蚜。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,879評(píng)論 1 290
  • 那天窝爪,我揣著相機(jī)與錄音弛车,去河邊找鬼。 笑死蒲每,一個(gè)胖子當(dāng)著我的面吹牛纷跛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播邀杏,決...
    沈念sama閱讀 39,028評(píng)論 3 409
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼贫奠,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了望蜡?” 一聲冷哼從身側(cè)響起唤崭,我...
    開(kāi)封第一講書(shū)人閱讀 37,773評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎脖律,沒(méi)想到半個(gè)月后浩姥,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,220評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡状您,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,550評(píng)論 2 327
  • 正文 我和宋清朗相戀三年勒叠,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了兜挨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,697評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡眯分,死狀恐怖拌汇,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情弊决,我是刑警寧澤噪舀,帶...
    沈念sama閱讀 34,360評(píng)論 4 332
  • 正文 年R本政府宣布,位于F島的核電站飘诗,受9級(jí)特大地震影響与倡,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜昆稿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,002評(píng)論 3 315
  • 文/蒙蒙 一纺座、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧溉潭,春花似錦净响、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,782評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至畏陕,卻和暖如春配乓,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背惠毁。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,010評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工犹芹, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人仁讨。 一個(gè)月前我還...
    沈念sama閱讀 46,433評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像实昨,于是被迫代替她去往敵國(guó)和親洞豁。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,587評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容