Android com.android.support:preference-v7库的使用

以前使用android.preference包里面的类创建出来的偏好设置界面是没有兼容低版本的,后来发现com.android.support:preference库有对低版本做兼容,在低版本上面也可以有Material Design风格,于是对其作了一番研究。

1、应用的主题需要继承自Theme.AppCompat系列:


2、在build.gradle中添加以下依赖:

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

3、在应用的主题里面添加:

@style/PreferenceThemeOverlay.v14.Material

4、编写my_pref.xml文件:




    

        

        
        

        

        
    


5、编写承载偏好设置的Fragment,这里继承自PreferenceFragmentCompat类:

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

效果图:


Android com.android.support:preference-v7库的使用_第1张图片
Screenshot_20180711-221330.jpg

6、对Preference节点进行删除、添加和修改:

@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、修改某个Preference的点击事件:

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

8、自定义ListPreference,可以自定义一个attrs,从XML文件中把属性值传进来;重写onBindViewHolder方法可以通过holder拿到对应的itemView,这样便可以对itemView里面的内容进行修改,这里我的itemView是自定义的,布局通过android:layout="@layout/item_view"进行设置:

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、对CheckBoxPreference和SwitchPreference的自定义类似,如果只想修改右边的控件(将Switch修改成自定义的View)可以在对应的Preference中添加android:widgetLayout="@layout/switch_layout",再自定义一个类继承自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时总感觉很奇怪,不知道为什么默认的EditTextPreference弹窗这么不好看(Google自己的规范上面都说Dialog内容到左右的边距为24dp):
默认的EditTextPreference


Android com.android.support:preference-v7库的使用_第2张图片
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里面传进来,在这里用getContext拿到的Context是ContextThemeWrapper,MainActivity mainActivity = (MainActivity) getContext();这样强转是会报错的。

//Fragment中set进来
MyEditTextPreference editTextPreference = (MyEditTextPreference) findPreference("key_8");
editTextPreference.setActivity(getActivity());

12、修改Preference的样式:

@color/colorAccent
#FFFF00FF
#FF666666
#FF00FFFF
Android com.android.support:preference-v7库的使用_第3张图片
Screenshot_20180713-213210.jpg

13、自定义EditTextPreference在低版本手机中碰到过选中文字背景颜色不是你设置的颜色的情况:

#FF0000FF
Android com.android.support:preference-v7库的使用_第4张图片
a.png

你可能感兴趣的:(Android com.android.support:preference-v7库的使用)