admin管理员组文章数量:1516870
Preference
基本上每个应用都有一个设置(首选项)界面, Google其实提供了默认的设置界面实现方式. 介绍下
Preference该类拥有多个直接或间接的子类, 这些子类可以组成不同内容的首选项界面. 和一般界面不同的
关键类:
- Preference 普通
- RingtonePreference 铃声
- CheckBoxPreference 选择按钮
- SwitchPreference 切换按钮
- PreferenceGroup(抽象类)
- PreferenceCategory 分类
- PreferenceScreen 首选项界面
- DialogPreference (抽象类)
- ListPreference 列表
- EditTextPreference 输入框
- MultiSelectListPreference 多选
- RingtonePreference 铃声
- PreferenceActivity 首选项界面
- PreferenceFragment 首选项片段
- PreferenceViewHolder
首选项
可以通过在res/xml目录下创建一个XML文件来控制显示一个首选项界面内容, 一般命名为preference.xml.
PreferenceActivity
在android3.0以下应使用继承PreferenceActivity方式实现(因为Fragment是3.0之后才有的), 但是如果需要使用多面板模式就必须使用这种方法
public class MainActivity extends PreferenceActivity {@Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//setContentView(R.layout.activity_main); 不允许使用一般布局addPreferencesFromResource(R.xml.preference);}
}
复制代码PreferenceFragment
在Android3.0或以上应采用Fragment的形式, 相对Activity更加灵活和效率. 使用方法和一般Fragment一样.
public static class SettingsFragment extends PreferenceFragment {@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);addPreferencesFromResource(R.xml.preferences);}...
}
复制代码属性
以下介绍的是所有Preference标签通用的属性
-
android:key
等同于SharePreference中的key值, 对于某些不需要存储数据的首选项可以不填写该属性(例如PreferenceCategory和PreferenceScreen)
-
android:title
提供用户可见的标题
-
android:defaultValue
在SharePreference中的默认值
-
android:summary
描述性文字
-
android:icon
图标
示例
演示所有的标签
<PreferenceScreen xmlns:android="" android:key="@string/app_name"><CheckBoxPreference android:title="CheckBoxPreference"/><SwitchPreference android:title="SwitchPreference"/><PreferenceCategory android:title="PreferenceCategory"/><ListPreference android:title="ListPreference"/><EditTextPreference android:title="EditTextPreference"/><MultiSelectListPreference android:title="MultiSelectListPreference"/><RingtonePreference android:title="RingtonePreference"/><Preference android:title="Preference"/>
</PreferenceScreen>
复制代码PreferenceScreen
表示一个首选项界面(首选项布局必须以该标签为根标签)
<PreferenceScreen xmlns:android=""></PreferenceScreen>
复制代码PreferenceCategory
首选项界面中的分类, 分类的颜色默认是主题ColorAccount
该Preference没有分割线, 如果想去除分割线可以考虑自定义该PreferenceCategory
ListPreference
首选项中的列表
列表需要两个必须的选项.如果没有就Crash
- 列表键(标题)
- 列表值
<ListPreferenceandroid:entries="@array/setting_list"android:entryValues="@array/setting_list_values"android:title="ListPreference"/>
复制代码列表对话框还可以修改, 其实只要是DialogPreference的子类都支持这些属性.
这些属性分别对应对话框的
- 图标
- 布局
- 消息(和传统对话框一样如果设置了消息就没用了列表)
- 标题
EditTextPreference
输入首选项
void onSetInitialValue (boolean restoreValue, Object defaultValue)
复制代码SwitchPreference
开关描述属性, 该属性CheckBoxPreference同样支持
<SwitchPreferenceandroid:summaryOff="关闭"android:summaryOn="打开"android:title="SwitchPreference"/>
复制代码监听器
点击事件
getPreferenceScreen().setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {@Override public boolean onPreferenceClick(Preference preference) {return false;}
});
复制代码属性
android:title // 标题android:summary // 副标题android:enabled // 是否可用android:selectable // 是否可选, 如果处于不可选状态将没有分割线, 也不可用状态android:icon // 图标android:key // sharepreference keyandroid:defaultValue // 默认值android:order // 排列顺序android:shouldDisableView // 如果处于不可用状态, 是否"灰色"android:persistent // 是否持久化(即存储到SharePreference)android:fragment // 无效果
复制代码自定义
自定义视图
void setLayoutResource (int layoutResId)void setWidgetLayoutResource (int widgetLayoutResId)void setDialogLayoutResource (int dialogLayoutResId)
复制代码前面提到过onCreate里面不能setContent否则会报空指针, 其实只是因为找不到对应的id
@Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_setting);addPreferencesFromResource(R.xml.demo);
}
复制代码layout/activity_setting.xml
<LinearLayout xmlns:android=""xmlns:app=""android:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"><android.support.v7.widget.Toolbarandroid:id="@+id/toolbar"android:navigationIcon="@drawable/ic_action_back"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="@color/colorPrimary"app:popupTheme="@style/Theme.AppCompat.Light"app:theme="@style/Theme.AppCompat" /><FrameLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:padding="15dp" ><ListViewandroid:id="@android:id/list"android:layout_width="match_parent"android:layout_height="match_parent" /></FrameLayout></LinearLayout>
复制代码重写
介绍下官方重写示例: 自定义DialogPreference
自定义 DialogPreference 可以使用下面的构造函数来声明布局并为默认的肯定和否定对话框按钮指定文本:
public class NumberPickerPreference extends DialogPreference {public NumberPickerPreference(Context context, AttributeSet attrs) {super(context, attrs);setDialogLayoutResource(R.layout.numberpicker_dialog);setPositiveButtonText(android.R.string.ok);setNegativeButtonText(android.R.string.cancel);setDialogIcon(null);}...
}
复制代码或者你通过重写
@Override protected View onCreateDialogView() {View view = View.inflate(getContext(), R.layout.dialog_preference, null);return view;}
复制代码保存设置的值
如果设置的值为整型数或是用于保存布尔值的 persistBoolean(),则可通过调用 Preference 类的一个 persist*() 方法(如 persistInt())随时保存该值。
**注:**每个 Preference 均只能保存一种数据类型,因此您必须使用适合自定义 Preference 所用数据类型的 persist*() 方法。
至于何时选择保留设置,则可能取决于要扩展的 Preference 类。如果扩展 DialogPreference,则只能在对话框因肯定结果(用户选择“确定”按钮)而关闭时保留该值。
当 DialogPreference 关闭时,系统会调用 onDialogClosed() 方法。该方法包括一个布尔参数,用于指定用户结果是否为“肯定”;如果值为 true,则表示用户选择的是肯定按钮且您应该保存新值。 例如:
@Override
protected void onDialogClosed(boolean positiveResult) {// 当点击确定时保存数据if (positiveResult) {persistInt(mNewValue);}
}
复制代码关于默认值
首先需要设置一个默认值
重写onGetDefaultValue查找该默认值并返回
@Override
protected Object onGetDefaultValue(TypedArray a, int index) {return a.getInteger(index, 0);
}
复制代码重写onSetInitialValue判断是进行恢复数据还是初始化默认值.
如果没有实现上面的方法defaultValue是为null. 并且restorePersistedValue为false时并不会回调该方法
/*** @param restorePersistedValue 是否有可恢复数据* @param defaultValue 默认值*/
@Override
protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {if (restorePersistedValue) {// 恢复数据mCurrentValue = this.getPersistedInt(DEFAULT_VALUE);} else {// 初始化默认值mCurrentValue = (Integer) defaultValue;persistInt(mCurrentValue);}
}
复制代码属性
依赖
通过填写其他Preference的title可以依赖他. 如果是相同的Preference则会同步属性, 如果不同则会同步其是否可用状态.
android:dependency="notifications_new_message"
复制代码自定义视图
前面介绍过代码自定义, 这里介绍下XML Attributes
android:layout // 自定义显示内容android:widgetLayout // 同样是自定义显示内容
复制代码区分:
layout
<img src=".jpg" width="250"/> 复制代码widgetLayout
可以看出layout属于完全自定义, 而widgetLayou仍然被约束了边距. 分割线两者都有
更多
默认值
前面提过Preference标签都有一个defaultValue的属性, 该属性可以设置一个首选项的默认值.
除了在XML中设置还需要在Application或者主Activity(仅推荐非强制)中执行重置默认值操作
PreferenceManager.setDefaultValues(this, R.xml.advanced_preferences, false);
复制代码参数:
-
上下文Context
-
首选项XML
-
首选项XML中有一个键为
KEY_HAS_SET_DEFAULT_VALUES的值表示是否设置过默认值.这第三个参数如果为true则不论是否设置过默认值都进行初始化重置, 如果为false则要判断是否设置过默认值.
子屏幕显示
经常可以看到应用的详细设置不在首选项界面的主界面而是需要继续打开一个子屏幕进行更详细的设置
标头: 通过将preference-headers设为根标签, 用header来控制多个Fragment作为子屏幕
<preference-headers xmlns:android=""><header android:fragment="com.tianyachuanmei.preperence.AboutFragment" android:title="关于" /><header android:fragment="com.tianyachuanmei.preperence.MoreFragment" android:title="更多"/>
</preference-headers>
复制代码该方法不能通过以下方法加载, 同样该方法也被废弃.
addPreferencesFromResource(R.xml.pref_headers);
复制代码通过重写PreferenceActivity的方法来加载XML, 如果不是headers不需要重写该方法()
@Override @TargetApi(Build.VERSION_CODES.HONEYCOMB) public void onBuildHeaders(List<Header> target) {loadHeadersFromResource(R.xml.pref_general, target);}
复制代码Tip: loadHeadersFromResource不能加载非HeadersXML文件, 否则Crash.
点击事件**: 通过给Preference指定跳转的Activity来实现子屏幕
<PreferenceScreen xmlns:android=""><Preferenceandroid:title="@string/prefs_category_one"android:summary="@string/prefs_summ_category_one" ><intentandroid:targetPackage="com.example.prefs"android:targetClass="com.example.prefs.SettingsActivity"android:action="com.example.prefs.PREFS_ONE" /></Preference><Preferenceandroid:title="@string/prefs_category_two"android:summary="@string/prefs_summ_category_two" ><intentandroid:targetPackage="com.example.prefs"an droid:targetClass="com.example.prefs.SettingsActivity"android:action="com.example.prefs.PREFS_TWO" /></Preference>
</PreferenceScreen>
复制代码多面板
多面板需要使用PreferenceActivity来实现, 通过重写onIsMultiPane返回true来启用多面板模式
@Override public boolean onIsMultiPane() {// 以下是判断当前设备是否是大屏幕return (getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_XLARGE;}
复制代码意图(Intent)
<PreferenceScreenandroid:summary="summary_intent_preference"android:title="title_intent_preference" ><intentandroid:action="android.intent.action.VIEW"android:data="" />
</PreferenceScreen>
复制代码您可以使用以下属性创建隐式和显式 Intent:
-
android:action要分配的操作(按照
setAction()方法)。 -
android:data要分配的数据(按照
setData()方法)。 -
android:mimeType要分配的 MIME 类型(按照
setType()方法)。 -
android:targetClass组件名称的类部分(按照
setComponent()方法)。 -
android:targetPackage组件名称的软件包部分(按照
setComponent()方法)。
<PreferenceScreen xmlns:android=""><Preferenceandroid:title="prefs_category_one"android:summary="prefs_summary_category_one"><!-- 这里android:targetPackage是应用程序的Context,而android:targetClass的路径在子包settings下 --><!-- 如果把 android:targetPackage="com.demo.artshell.uidemo.settings" 运行时找不到Activity --><intentandroid:action="prefs_category_action_ONE"android:targetPackage="com.demo.artshell.uidemo"android:targetClass="com.demo.artshell.uidemo.settings.SupportOldVersionAndReusedActivityOrFragment$ReusedActivity"><!-- 官网没有说明,但确实可以通过<extra>传附加信息 getIntent().getStringExtra("reused_key") --><extraandroid:name="reused_key"android:value="reused_fragment_two"/></intent></Preference><Preferenceandroid:title="prefs_category_two"android:summary="prefs_summary_category_two"><intentandroid:action="prefs_category_action_TWO"android:targetPackage="com.demo.artshell.uidemo"android:targetClass="com.demo.artshell.uidemo.settings.SupportOldVersionAndReusedActivityOrFragment$ReusedActivity"/></Preference>
</PreferenceScreen>
复制代码本文标签: Preference
版权声明:本文标题:Preference 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.betaflare.com/biancheng/1706814714a703415.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。


发表评论