Android Preference初探,另一种布局方式

来源:互联网 发布:c语言a=b>c 编辑:程序博客网 时间:2024/05/01 11:12

记得android五大数据存储中有个SharePreferences,其他四种分别是:

  1. SQLite数据库
  2. ContentProvider(内容提供者)
  3. 文件存储
  4. 网络存储

这里简单回顾一下SharePreference是的使用:

// 1. 得到sharedPreferences,第一个参数指定SharePreference保存的xml文件的文件名,第二个参数是SharedPreferences模式SharedPreferences sharedPreferences = getSharedPreferences("demo", Activity.MODE_PRIVATE);// 2. 保存数据(记得commit)SharedPreferences.Editor edit = sharedPreferences.edit();edit.putString("key","value");edit.commit();// 3. 获取数据String value = sharedPreferences.getString("key", "default");

其实,SharePreferences底层是将数据以键值对的方式存储保存在/data/data/package name/shared_prefs下的一个xml文件中。似乎键值对这种数据传递方式很好用,如起源于javascript的json数据格式被广泛应用到各种语言中,致使Android中又多了Json数据解析,而json数据解析似乎又成为了程序员的必修课,而Android Preference也离不开键值对,每个Preference都有一个键值对。

以前我们写布局都是在layout使用View编写布局,而今天我们使用的是Preference构建布局,通常是用在设置模块,这样可以让我们应用设置和系统设置视觉体验一样,风格统一。

1. Android内置Preference的使用

查看android.preference包目录,可以发现Android内置了许多Preference供我们使用。

这里写图片描述

其中比较常用的有Preference,CheckBoxPreference,EditTextPreference,ListPreference。下面我们动手简单的使用一下这些Preference。

步骤:

(1)在res/xml文件夹下建立xml文件,如:

<?xml version="1.0" encoding="utf-8"?><PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">    <PreferenceCategory android:title="@string/textView">        <Preference android:key="preference"            android:title="@string/show_text"            android:defaultValue="文本值"            android:summary="@string/text_summary" />    </PreferenceCategory>    <PreferenceCategory android:title="@string/edit_text">        <EditTextPreference android:key="edittext_preference"            android:title="@string/edit_text"            android:summary="@string/edit_summary"            android:dialogTitle="@string/edit_dialog_title">        </EditTextPreference>    </PreferenceCategory>    <PreferenceCategory android:title="@string/checkbox">        <CheckBoxPreference android:key="checkbox_preference1"            android:title="@string/selection_1"            android:summary="@string/selection_summary_1">        </CheckBoxPreference>    </PreferenceCategory>    <PreferenceCategory android:title="@string/single_selection">        <ListPreference android:key="list_preference"            android:title="@string/single_selection"            android:summary="@string/single_select_summary"            android:entries="@array/single_selection"            android:entryValues="@array/single_selection_value">        </ListPreference>    </PreferenceCategory>    <PreferenceCategory android:title="@string/toggle">        <SwitchPreference            android:key="switch_preference"            android:title="@string/toggle"            android:textOn="@string/on"            android:textOff="@string/off">        </SwitchPreference>    </PreferenceCategory></PreferenceScreen>

上面用到的内置Preference都会被系统自动显示在屏幕上,形成一种View。其中:

  • key属性一般都需要,它标识了这个Preference,相当于View的ID,必须唯一,无论是我们要在代码中得到这个Preference的实例还是要保存Preference的数据,都需要一个唯一的key。
  • summary属性就是显示在标题下面的摘要
  • PreferenceCategory用来给Preference设置分组。

(2)新建一个Activity继承PreferenceActivity,如:

public class SettingsActivity extends PreferenceActivity {    private static final String TAG = "SettingsActivity";    private SharedPreferences mDefaultSharedPreferences;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        addPreferencesFromResource(R.xml.activity_settings);    }}

在onCreate方法中调用addPreferencesFromResource()方法添加我们自定义的xml布局就ok了。

显示效果:

这里写图片描述

对于Preference的使用比较简单。除了上面的那种Preference分组外,我们还可以子屏幕的方式来给Preference进行分组,如将上面的xml修改为:

<?xml version="1.0" encoding="utf-8"?><PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">    <PreferenceScreen        android:key="text"        android:title="@string/text">        <Preference            android:title="@string/show_text"            android:defaultValue="文本值"            android:summary="@string/text_summary" />        <EditTextPreference android:key="edittext_preference"            android:title="@string/edit_text"            android:summary="@string/edit_summary"            android:dialogTitle="@string/edit_dialog_title">        </EditTextPreference>    </PreferenceScreen>    <PreferenceCategory android:title="@string/checkbox">        <CheckBoxPreference android:key="checkbox_preference1"            android:title="@string/selection_1"            android:summary="@string/selection_summary_1">        </CheckBoxPreference>    </PreferenceCategory>    <PreferenceCategory android:title="@string/single_selection">        <ListPreference android:key="list_preference"            android:title="@string/single_selection"            android:summary="@string/single_select_summary"            android:entries="@array/single_selection"            android:entryValues="@array/single_selection_value">        </ListPreference>    </PreferenceCategory>    <PreferenceCategory android:title="@string/toggle">        <SwitchPreference            android:key="switch_preference"            android:title="@string/toggle"            android:summary="@string/switch_summary"            android:textOn="@string/on"            android:textOff="@string/off">        </SwitchPreference>    </PreferenceCategory></PreferenceScreen>

则效果图:

这里写图片描述

点击文本组后:

这里写图片描述

可以看到这种分组则是利用PreferenceScreen嵌套包裹Preference的方式来分组的,会将包裹的Preference隐藏,点击该分组后则会显示在一个子屏幕中。

2. Preference点击事件的监听

有了视图,那么用户会操作视图,如点击一下多选框,则需要我们在代码中监听Preference的点击事件。

观察发现,有3个关于Preference事件的方法:

  1. onPreferenceClick()(设置OnPreferenceClickListener)
  2. onPreferenceTreeClick()
  3. onPreferenceChange()(设置OnPreferenceChangeListener)

这三个事件的执行顺序一般也是上面的顺序,其中在onPreferenceClick返回值中返回true时则不会执行第三个方法。

监听到点击事件后,我们可以执行我们自己的操作,如打开一个新的Activity,弹出对话框或打开一个网页等等,不过可以用Intent的操作,还有更简单的方法。

只需在相应的Preference下添加一个intent,即可执行intent:

<Preference            android:key="preference"            android:title="@string/show_text"            android:defaultValue="文本值"            android:summary="@string/text_summary">            <intent android:action="android.intent.action.VIEW"                android:data="http://www.baidu.com" />        </Preference>

3. Preference设置默认值

通过Preference的defaultValue属性设置默认值,这个值系统会在用户第一次打开该应用的时候保存到SharePreferences中作为该Preference的默认值。

4. Preference数据的保存

每个Preference都有一个键值对,系统根据这个键值对自动将Preference的值保存到SharePreferences中,当我们需要根据Preference的值确定用户的行为时,如开关打开和开关关闭状态,我们代码的执行逻辑。这个时候,我们只需要读取SharePreference即可得到这个值。

getPreferenceManager().getDefaultSharedPreferences(this)

通过上面的代码,我们可以得到系统保存Preference值的那个SharedPreferences,然后我们可以与SharedPreferences交互。

5. Preference Headers的使用

Preference Headers是Android 3.0之后引入的可以使得第一个屏幕只显示分组列表,而不是显示分组的子屏幕列表,这也是除了用PreferenceScreen嵌套构建子屏幕的另一种方法。

在Android 3.0及更高的版本中,我们可以使用Headers功能构建子屏幕

步骤:

(1)编写preference headers的xml

<?xml version="1.0" encoding="utf-8"?><preference-headers xmlns:android="http://schemas.android.com/apk/res/android">    <header        android:title="@string/prefs_category_one"        android:fragment="com.example.lt.preference.SwitchFragment"        android:summary="@string/prefs_summ_category_one">        <!-- key/value pairs can be included as arguments for the fragment. -->        <extra android:name="type" android:value="数据连接" />    </header>    <header        android:title="@string/prefs_category_two"        android:fragment="com.example.lt.preference.SwitchFragment"        android:summary="@string/prefs_summ_category_two" >        <!-- key/value pairs can be included as arguments for the fragment. -->        <extra android:name="type" android:value="多选框" />    </header></preference-headers>

其中:

  • fragment属性指定了当我们点击这个header的时候跳转到的fragment
  • extra属性的key和value会被封装到Bundle中,然后使用fragment的getArguments()得到这个Bundle从而得到key对应的value

(2)编写子屏幕的xml布局和代码

数据连接的xml

<?xml version="1.0" encoding="utf-8"?><PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">    <SwitchPreference        android:key="switch_preference1"        android:title="@string/data_connection"        android:summary="@string/data_connection_summary"        android:textOn="@string/on"        android:textOff="@string/off">    </SwitchPreference>    <SwitchPreference        android:key="switch_preference2"        android:title="@string/wifi_connection"        android:summary="@string/wifi_connection_summary"        android:textOn="@string/on"        android:textOff="@string/off">    </SwitchPreference></PreferenceScreen>

多选框的xml

<?xml version="1.0" encoding="utf-8"?><PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">    <CheckBoxPreference        android:key="checkbox1"        android:title="@string/selection_1"        android:summary="@string/selection_summary_1">    </CheckBoxPreference>    <CheckBoxPreference        android:key="checkbox2"        android:title="@string/selection_2"        android:summary="@string/selection_summary_2">    </CheckBoxPreference></PreferenceScreen>

这里编写的两个xml布局对应了上面的两个header,所以还需要编写Fragment

public class SwitchFragment extends PreferenceFragment{    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        String type = getArguments().getString("type");        if(type.equals("数据连接")){            addPreferencesFromResource(R.xml.switch_header);        }else{            addPreferencesFromResource(R.xml.checkbox_header);        }    }}

可以看到这里根据xml中header的extra属性指定的value加载不同的布局,是因为我们两个header共用了这个Fragment。

(3)编写主屏幕代码

主屏幕需要用一个PreferenceActivity显示:

public class SettingsActivity extends PreferenceActivity{    @Override    protected boolean isValidFragment(String fragmentName) {        return true;    }    @Override    public void onBuildHeaders(List<Header> target) {        loadHeadersFromResource(R.xml.preference_headers,target);    }}

说明:

  • 不需要重写OnCreate,只需要重写onBuildHeaders加载主屏幕的xml,因为这个Activity只加载Headers。
  • 需要重写isValidFragment并返回true,否则运行会出错。

ok,以下是显示截图:

这里写图片描述

这里写图片描述

这里写图片描述

如果需要兼容Android 3.0及更低版本,则需要利用intent标签,我们可以在主屏幕中添加两个Preference,并设置intent标签,由于Andoroid 3.0以下没有Fragment,也就没有PreferenceFragment,所以主屏幕需要一个Activity,子屏幕也需要一个Activity(公用),通过intent的Action的值在子屏幕activity的onCreate方法中使用addPreferencesFromResource()方法加载不同的xml布局,记得判断一下Android版本。

总结:Android Preference作为Android中新的一种布局方式,通常用在Settings模块中,使得我们自己应用的设置风格也能像系统设置一样,达成一种视觉上的统一,其使用比较简单,有点类似于View。

0 0
原创粉丝点击