PreferenceActivity Android 4.0及更早版本

PreferenceActivity Android 4.0及更早版本,android,preferenceactivity,Android,Preferenceactivity,在Android 4.0的ApiDemos中尝试不同的首选项活动,我在代码中看到一些方法在PreferencesFromCode.java中被弃用,例如 所以我的问题是:如果我使用PreferenceFragment,它会适用于所有版本还是仅适用于3.0或4.0及以上版本 如果是这样,我应该使用什么同样适用于2.2和2.3?首选项片段将不适用于2.2和2.3(仅适用于API级别11及以上)。如果您希望提供最佳的用户体验,并且仍然支持较旧的Android版本,那么这里的最佳实践似乎是实现两个Pre

在Android 4.0的ApiDemos中尝试不同的首选项活动,我在代码中看到一些方法在PreferencesFromCode.java中被弃用,例如

所以我的问题是:如果我使用PreferenceFragment,它会适用于所有版本还是仅适用于3.0或4.0及以上版本


如果是这样,我应该使用什么同样适用于2.2和2.3?

首选项片段
将不适用于2.2和2.3(仅适用于API级别11及以上)。如果您希望提供最佳的用户体验,并且仍然支持较旧的Android版本,那么这里的最佳实践似乎是实现两个
PreferenceActivity
类,并在运行时决定调用哪个类。然而,此方法仍然包括调用不推荐的API,但您无法避免

例如,您有一个
首选项\u headers.xml

<preference-headers xmlns:android="http://schemas.android.com/apk/res/android" > 
    <header android:fragment="your.package.PrefsFragment" 
        android:title="...">
        <extra android:name="resource" android:value="preferences" />
    </header>
</preference-headers>
然后您需要一个
首选片段
的实现:

public static class PrefsFragment extends PreferenceFragment {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);
    }
}
最后,您需要两个
PreferenceActivity
的实现,用于支持或不支持
PreferenceFragments
的API级别:

public class PreferencesActivity extends PreferenceActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);
        addPreferencesFromResource(R.xml.other);
    }
}
以及:

公共类OtherPreferencesActivity扩展了PreferenceActivity{
@凌驾
public void onBuildHeaders(列表目标){
loadHeadersFromResource(R.xml.preference_头,目标);
}
}
在您希望向用户显示首选项屏幕时,您可以决定启动哪个屏幕:

if (Build.VERSION.SDK_INT < 11) {
    startActivity(new Intent(this, PreferencesActivity.class));
} else {
    startActivity(new Intent(this, OtherPreferencesActivity.class));
}
if(Build.VERSION.SDK\u INT<11){
startActivity(新意图(这个,PreferencesActivity.class));
}否则{
startActivity(新意图(this,OtherPreferencesActivity.class));
}

因此,基本上,每个片段都有一个xml文件,手动加载每个xml文件,API级别<11,两个活动使用相同的首选项。

@Mef您的答案可以更加简化,这样您就不需要同时使用PreferencesActivity和OtherPreferencesActivity(有两个preferences是一个PITA)

我发现您可以将onBuildHeaders()方法放入PreferencesActivity中,v11之前的Android版本不会抛出任何错误。将loadHeadersFromResource()放在onBuildHeaders中不会在2.3.6上引发和异常,但在Android 1.6上引发和异常。经过一些修改,我发现以下代码可以在所有版本中工作,因此只需要一个活动(大大简化了问题)

2013年10月更新:
Eclipse/Lint将警告您使用不推荐使用的方法,但忽略该警告。我们只是在必要的时候才使用这个方法,也就是说,我们没有v11+风格的首选项,必须使用它,这是可以的。当你考虑到不推荐的代码时,不要害怕它,Android不会很快删除不推荐的方法。如果它真的发生了,您甚至不再需要这个类,因为您将被迫只针对较新的设备。不推荐使用的机制是为了警告您,在最新的API版本上有更好的方法来处理某些事情,但是一旦您考虑了它,您就可以从那时起安全地忽略该警告。删除对不推荐的方法的所有调用只会导致强制您的代码只在较新的设备上运行,从而完全不需要向后兼容。

以前的答案的问题是,它会将所有首选项堆叠到Honecomb设备上的单个屏幕上(由于多次调用
addPreferenceFromResource())

如果您首先需要屏幕作为列表,然后需要带有首选项的屏幕(例如使用首选项标题),则应使用

UnifiedReference是一个用于处理所有版本的 来自API v4及更高版本的Android首选项包


我想指出的是,如果您从“支持带有首选项标题的旧版本”一节开始,一直到下一节,这将更有意义。那里的导游很有帮助,而且工作得很好。下面是一个遵循他们指南的明确示例:

因此,在蜂巢之前,先从android系统的文件首选项_header_legacy.xml开始

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<Preference 
    android:title="OLD Test Title"
    android:summary="OLD Test Summary"  >
    <intent 
        android:targetPackage="example.package"
        android:targetClass="example.package.SettingsActivity"
        android:action="example.package.PREFS_ONE" />
</Preference>
AndroidManifest.xml,在我的
标记之间添加了此块

<activity 
   android:label="@string/app_name"
   android:name="example.package.SettingsActivity"
   android:exported="true">
</activity>

最后,对于
标记

<wallpaper xmlns:android="http://schemas.android.com/apk/res/android"
android:description="@string/description"
android:thumbnail="@drawable/ic_thumbnail"
android:settingsActivity="example.package.SettingsActivity"
/>

我正在使用,它在
mavenCentral
中有一个
AAR
,因此如果使用
Gradle
,您可以很容易地将其包括在内


编译'com.github.machinarius:preferencefragment:0.1.1'

深刻的答案。确实需要,因为谷歌没有给我们适当的文档,使Android应用程序向后兼容。直到最近事情才开始改变,不过(见上面的评论)好主意,唯一的问题是当你不是开始活动的人时,因此你无法决定开始哪项活动。您使用的是API级检测,而不是特性检测(使用类加载器检查PreferenceFragment是否存在)。编辑build.prop文件使其从API 10上升到API 11(或更高)的用户将发生崩溃。此处记录了这一点:@Tom您可以通过使用垫片活动来解决“不是启动活动的人”的问题,该活动只启动新的prefs活动,然后调用finish。当然,它应该远离历史/倒退。很好的解决方案,谢谢。不幸的是,当您需要将一些编程生成的参数传递给preferences片段时,它就不起作用了。目前还没有与preferences相关的参数,但是Google开始在开发者的网站上提供有关pre-Honeycomb设备兼容性问题的有用信息:PreferenceFragment有一个第三方后台端口。正如@pcans在下面评论的那样,答案现在出现在Android官方文档中:1.6版的异常是因为Dalvik试图加载所有方法(或检查它们是否存在),即使它们在运行时没有被调用。这种行为在2.0中已经改变,因此2.3.6中没有例外。
startActivity(new Intent(this, PreferencesActivity.class);
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<Preference 
    android:title="OLD Test Title"
    android:summary="OLD Test Summary"  >
    <intent 
        android:targetPackage="example.package"
        android:targetClass="example.package.SettingsActivity"
        android:action="example.package.PREFS_ONE" />
</Preference>
<preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
<header 
    android:fragment="example.package.SettingsFragmentOne"
    android:title="NEW Test Title"
    android:summary="NEW Test Summary" />
</preference-headers>
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
        <CheckBoxPreference
        android:key="pref_key_auto_delete"
        android:summary="@string/pref_summary_auto_delete"
        android:title="@string/pref_title_auto_delete"
        android:defaultValue="false" />
</PreferenceScreen>
package example.project;
import java.util.List;
import android.annotation.SuppressLint;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceActivity;

public class SettingsActivity extends PreferenceActivity{
final static String ACTION_PREFS_ONE = "example.package.PREFS_ONE";

@SuppressWarnings("deprecation")
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    String action = getIntent().getAction();
    if (action != null && action.equals(ACTION_PREFS_ONE)) {
        addPreferencesFromResource(R.xml.preferences);
    }
    else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
        // Load the legacy preferences headers
        addPreferencesFromResource(R.xml.preference_header_legacy);
    }
}

@SuppressLint("NewApi")
@Override
public void onBuildHeaders(List<Header> target) {
    loadHeadersFromResource(R.xml.preference_header, target);
}
}
package example.project;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.preference.PreferenceFragment;

@SuppressLint("NewApi")
public class SettingsFragmentOne extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    addPreferencesFromResource(R.xml.preferences);
}
}
<activity 
   android:label="@string/app_name"
   android:name="example.package.SettingsActivity"
   android:exported="true">
</activity>
<wallpaper xmlns:android="http://schemas.android.com/apk/res/android"
android:description="@string/description"
android:thumbnail="@drawable/ic_thumbnail"
android:settingsActivity="example.package.SettingsActivity"
/>