在PreferenceActivity中使用什么代替“ addPreferencesFromResource”?

最后都变了- 提交于 2020-02-26 05:17:53

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

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

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


#1楼

要向上述正确答案添加更多信息,请阅读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楼

@Garret Wilson非常感谢! 作为android编码的新手,我一直困扰着首选项不兼容问题达数小时之久,但令我失望的是,他们不赞成将某些方法/方法用于较旧的API不支持的新方法/方法必须采取各种变通办法来使您的应用在各种设备上运行。 真令人沮丧!

您的课程很棒,因为它使您可以按照喜好使用新的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,所以我创建了一个新变量来存储此值。

我希望这对其他人有用。

PS:对不起,我的观点是对的,但是,当您初来乍到并发现这样的障碍时,您会无奈地感到沮丧!


#3楼

除了使用例外,还可以使用:

if (Build.VERSION.SDK_INT >= 11)

和使用

@SuppressLint("NewApi")

禁止显示警告。


#4楼

我的方法非常接近Garret Wilson的方法 (谢谢,我投票赞成;)

此外,它还提供与Android <3的向下兼容性。

我刚刚意识到我的解决方案更接近Kevin Remo的解决方案。 它只是一点点的清洁(因为它不依赖于“ expection”反模式 )。

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


#5楼

与其使用PreferenceActivity直接加载首选项, AppCompatActivity使用AppCompatActivity或加载PreferenceFragmentCompat等效项来加载您的首选项。 它是支持库(现在为Android Jetpack)的一部分,并提供与API 14的兼容性。

build.gradlebuild.gradle选项支持库添加一个依赖项:

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

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

对于您的活动,创建一个新的活动类。 如果您使用的是实质性主题,则应该扩展AppCompatActivity ,但是您可以灵活地做到这一点:

public class MyPreferencesActivity extends AppCompatActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.my_preferences_activity)
        if (savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction()
                    .replace(R.id.fragment_container, MyPreferencesFragment())
                    .commitNow()
        }
    }
}

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

public class MyPreferencesFragment extends PreferenceFragmentCompat {

    @Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
        setPreferencesFromResource(R.xml.my_preferences_fragment); // Your preferences fragment
    }
}

有关更多信息,请阅读Android Developers 文档中的PreferenceFragmentCompat

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!