前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android’s PreferenceActivity for all API versions

Android’s PreferenceActivity for all API versions

作者头像
小小工匠
发布2021-08-16 10:15:06
2080
发布2021-08-16 10:15:06
举报
文章被收录于专栏:小工匠聊架构

官方文档

I have spent the last few days learning about how to use the new Android PreferenceFragment which requires PreferenceActivity to override a new v11 (Honeycomb) method called onBuildHeaders(). Unfortunately, the documentation is not very clear how one would create a single PreferenceActivity that could play well in all versions, utilizing the newest features if you have it and avoiding an app crash on older Android versions. I encountered several solutions to this issue by creating two different activities for the two different mechanisms requiring two entries in your AndroidManifest.xml file. Having two different PreferenceActivities means if you have library code that extends that class, you now have to duplicate it. Then, if your app descends your library class, now has to be duplicated yet again. The end result is … less than ideal.

Thankfully, after spending a great deal of time on the subject, I have come up with a single class solution that will work in all Android versions. A couple of the newer methods need to be found using reflection and based off of them, in addition to using the newly introduced xml file of , allow for a single class solution.

First, take your old xml layouts and break them up into several files based on how you would like to see them categorized using the new header format. Simply breaking them apart so that each PreferenceCategory has its own file is a good start. For our example here, we shall assume there are 3 such files, all in the res/xml folder: app_prefs_cat1.xml, app_prefs_cat2.xml, and app_prefs_cat3.xml

Now let us create the descendant PrefsActivity class:

代码语言:javascript
复制
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;

public class PrefsActivity extends PreferenceActivity {
    protected Method mLoadHeaders = null;
    protected Method mHasHeaders = null;

    /**
     * Checks to see if using new v11+ way of handling PrefsFragments.
     * @return Returns false pre-v11, else checks to see if using headers.
     */
    public boolean isNewV11Prefs() {
        if (mHasHeaders!=null && mLoadHeaders!=null) {
            try {
                return (Boolean)mHasHeaders.invoke(this);
            } catch (IllegalArgumentException e) {
            } catch (IllegalAccessException e) {
            } catch (InvocationTargetException e) {
            }
        }
        return false;
    }

    @Override
    public void onCreate(Bundle aSavedState) {
        //onBuildHeaders() will be called during super.onCreate()
        try {
            mLoadHeaders = getClass().getMethod("loadHeadersFromResource", int.class, List.class );
            mHasHeaders = getClass().getMethod("hasHeaders");
        } catch (NoSuchMethodException e) {
        }
        super.onCreate(aSavedState);
        if (!isNewV11Prefs()) {
            addPreferencesFromResource(R.xml.app_prefs_cat1);
            addPreferencesFromResource(R.xml.app_prefs_cat2);
            addPreferencesFromResource(R.xml.app_prefs_cat3);
        }
    }

    @Override
    public void onBuildHeaders(List

On older Android versions, the reflected methods will be null and thus avoids calling the newer methods, using the older mechanism of adding the various preference xml files in onCreate(). In order to use the new Honeycomb (v11+) preference mechanism, we need to create one more xml file – the newer xml file that ties all the category files together. The res/xml resource file “pref_headers.xml”:

代码语言:javascript
复制
<preference-headers
    xmlns:android="http://schemas.android.com/apk/res/android" >

<header android:fragment="my.domain.app.PrefsActivity$PrefsFragment"
    android:icon="@android:drawable/ic_menu_sort_by_size"
    android:title="Category 1 prefs" >
    <extra android:name="pref-resource" android:value="app_prefs_cat1" />
header>        

<header android:fragment="my.domain.app.PrefsActivity$PrefsFragment"
    android:icon="@android:drawable/ic_menu_gallery"
    android:title="Category 2 prefs" >
    <extra android:name="pref-resource" android:value="app_prefs_cat2" />
header>

<header android:fragment="my.domain.app.PrefsActivity$PrefsFragment"
    android:icon="@android:drawable/ic_menu_edit"
    android:title="Category 3 prefs" >
    <extra android:name="pref-resource" android:value="app_prefs_cat3" />
header>

<header
    android:icon="@drawable/icon_question"
    android:title="Blackmoon Info Tech Services"
    android:summary="link to BITS blog">
    <intent android:action="android.intent.action.VIEW"
            android:data="http://www.blackmoonit.com/2012/07/all_api_prefsactivity/" />
header>

preference-headers>

The first three headers list the three standard category xml files we created, but you are also free to add more items as you see fit, just remember that those will only be visible on devices with Android 3.0 or later.

Now that we have our xml file and single preference activity, we can define it in our AndroidManifest.xml as usual. Note: do not use android:launchMode=”singleTop” for your prefs activity or else it will break phones using 4.0+ by never showing more than just the header list.

代码语言:javascript
复制
<activity android:name="PrefsActivity"
        android:label="Settings"
        android:enabled="true" >
        <intent-filter>
            <category android:name="android.intent.category.PREFERENCE" />
        intent-filter>
    activity>

We can have a menu call our prefs activity with just one line:

代码语言:javascript
复制
startActivity(new Intent(this, PrefsActivity.class);

Now that you have a descendant class like this one, you can freely use it in all versions of Android and it will automatically use the newer mechanism where appropriate.

查看这里

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016/02/21 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档