在PreferenceActivity中使用什么而不是“addPreferencesFromResource”?

时间:2011-07-25 21:03:04

标签: android xml

我刚刚注意到,在Android的文档(Reference Entry)中,方法addPreferencesFromResource(int preferencesResId)被标记为已弃用

不幸的是,该方法的描述中没有提供替代方法。

为了将preferenceScreen.xml连接到匹配的PreferenceActivity,应该使用哪种方法?

6 个答案:

答案 0 :(得分:333)

方法描述中没有提供替代方法,因为首选方法(从API级别11开始)是实例化PreferenceFragment个对象以从资源文件加载首选项。请在此处查看示例代码:PreferenceActivity

答案 1 :(得分:187)

要向上面的正确答案添加更多信息,在阅读example from Android-er后,我发现您可以轻松地将您的偏好活动转换为偏好片段。如果您有以下活动:

public class MyPreferenceActivity extends PreferenceActivity
{
    @Override
    protected void onCreate(final Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.my_preference_screen);
    }
}

您必须做的唯一更改是创建内部片段类,将addPreferencesFromResources()移动到片段中,然后从活动中调用片段,如下所示:

public class MyPreferenceActivity extends PreferenceActivity
{
    @Override
    protected void onCreate(final Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        getFragmentManager().beginTransaction().replace(android.R.id.content, new MyPreferenceFragment()).commit();
    }

    public static class MyPreferenceFragment extends PreferenceFragment
    {
        @Override
        public void onCreate(final Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            addPreferencesFromResource(R.xml.my_preference_screen);
        }
    }
}

从碎片制作更复杂的偏好可能还有其他微妙之处;如果是这样,我希望有人在这里注意到它们。

答案 2 :(得分:37)

@Garret Wilson非常感谢你!作为Android编码的一个菜鸟,我已经坚持了这么多个小时的首选项不兼容问题,我发现它很令人失望他们不赞成使用某些方法/方法来处理旧的API不支持的新方法/方法不得不求助于各种变通方法,以使您的应用程序在各种设备上运行。真的很令人沮丧!

您的课程很棒,因为它允许您继续按照以前的方式使用新的API,但它不向后兼容。由于我正在尝试使用各种各样的设备,因此我对其进行了修改,以使其在API 11设备以及更新的API中运行:

import android.annotation.TargetApi;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.preference.PreferenceFragment;

public class MyPrefsActivity extends PreferenceActivity
{
    private static int prefs=R.xml.myprefs;

    @Override
    protected void onCreate(final Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        try {
            getClass().getMethod("getFragmentManager");
            AddResourceApi11AndGreater();
        } catch (NoSuchMethodException e) { //Api < 11
            AddResourceApiLessThan11();
        }
    }

    @SuppressWarnings("deprecation")
    protected void AddResourceApiLessThan11()
    {
        addPreferencesFromResource(prefs);
    }

    @TargetApi(11)
    protected void AddResourceApi11AndGreater()
    {
        getFragmentManager().beginTransaction().replace(android.R.id.content,
                new PF()).commit();
    }

    @TargetApi(11)
    public static class PF extends PreferenceFragment
    {       
        @Override
        public void onCreate(final Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            addPreferencesFromResource(MyPrefsActivity.prefs); //outer class
            // private members seem to be visible for inner class, and
            // making it static made things so much easier
        }
    }
}

成功测试了两个模拟器(2.2和4.2)。

为什么我的代码看起来很糟糕:

我是Android编码的菜鸟,我不是最好的java粉丝。

为了避免被弃用的警告并强制Eclipse允许我编译,我不得不诉诸注释,但这些似乎只影响类或方法,所以我不得不将代码移到两个新方法上以利用这个。

我不想在我复制和粘贴新的PreferenceActivity类的时候两次写我的xml资源id,所以我创建了一个新的变量来存储这个值。

我希望这对其他人有用。

P.S。:对不起我的观点,但是当你来到新的并找到这样的障碍时,你不能帮助它而是感到沮丧!

答案 3 :(得分:22)

我的方法非常接近Garret Wilson's(谢谢,我投票给你了;)

此外,它还向下兼容Android&lt; 3。

我刚认识到我的解决方案更接近Kevin Remo的解决方案。它只是一点点清洁(因为它不依赖于"expection" antipattern)。

public class MyPreferenceActivity extends PreferenceActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
            onCreatePreferenceActivity();
        } else {
            onCreatePreferenceFragment();
        }
    }

    /**
     * Wraps legacy {@link #onCreate(Bundle)} code for Android < 3 (i.e. API lvl
     * < 11).
     */
    @SuppressWarnings("deprecation")
    private void onCreatePreferenceActivity() {
        addPreferencesFromResource(R.xml.preferences);
    }

    /**
     * Wraps {@link #onCreate(Bundle)} code for Android >= 3 (i.e. API lvl >=
     * 11).
     */
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    private void onCreatePreferenceFragment() {
        getFragmentManager().beginTransaction()
                .replace(android.R.id.content, new MyPreferenceFragment ())
                .commit();
    }
}

对于“真实”(但更复杂)的示例,请参阅NusicPreferencesActivityNusicPreferencesFragment

答案 4 :(得分:6)

而不是例外,只需使用:

if (Build.VERSION.SDK_INT >= 11)

并使用

@SuppressLint("NewApi")

禁止警告。

答案 5 :(得分:0)

使用.transform()或等效项来加载inputChannel来加载偏好,而不是使用outputChannel来直接加载偏好。它是支持库(现在为Android Jetpack)的一部分,并提供与API 14的兼容性。

在您的PreferenceActivity中,为首选项支持库添加一个依赖项:

AppCompatActivity

注意:我们将假定您已经创建了首选项XML。

为您的活动创建一个新的活动类。如果您使用的是实质性主题,则应该扩展PreferenceFragmentCompat,但是您可以通过以下方式灵活使用:

build.gradle

现在重要的部分:创建一个片段,从XML加载您的首选项:

dependencies {
    // ...
    implementation "androidx.preference:preference:1.0.0-alpha1"
}

有关更多信息,请阅读AppCompatActivity的Android开发人员docs