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

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

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

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


#1楼

要向上述正确答案添加更多信息,请阅读Android-er示例,我发现您能够轻松地将您的偏好活动转换为偏好片断。 若是您有如下活动: git

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

您要作的惟一更改是建立一个内部片断类,将addPreferencesFromResources()移入片断,而后从活动中调用该片断,以下所示: github

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不支持的新方法/方法必须采起各类变通办法来使您的应用在各类设备上运行。 真使人沮丧! ide

您的课程很棒,由于它使您能够按照喜爱使用新的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)中测试成功。 gradle

为何个人代码如此糟糕: ui

我是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

相关文章
相关标签/搜索