在Android上创建多个preferences.xml文件时如何重用代码?

时间:2015-01-11 04:45:22

标签: android android-xml

我希望在我的应用中显示不同的偏好设置选项,具体取决于设备SDK和屏幕尺寸,但某些偏好设置将显示在所有设备上。我可以通过为每个可能的设备创建一个完整的preferences.xml文件来完成此任务,如下所示:

xml/preferences.xml

<PreferenceScreen>
    <!-- Preference 1 (all devices) -->
    <!-- Preference 2 (all devices) -->
</PreferenceScreen>

xml-v21/preferences.xml

<PreferenceScreen>
    <!-- Preference 1 (all devices) -->
    <!-- Preference 2 (all devices) -->
    <!-- Preference 3 (SDK 21 only) -->
</PreferenceScreen>

但考虑到屏幕尺寸和SDK的可能组合数量,这将很快变得笨拙。我真正想做的是在所有设备上使用相同的基本首选项列表,并动态混合特定于某些屏幕尺寸和SDK的其他首选项。我已经浏览了Android Providing Resources指南,但似乎以所述方式使用替代资源仍然需要我为每个屏幕大小和SDK组合创建一个单独的资源目录,并且需要大量的代码重复。我错过了这个问题的优秀解决方案吗?

1 个答案:

答案 0 :(得分:2)

您是否阅读过Settings guide?我的应用程序也动态地进行了很多更改,包括1)要显示的标题/片段,以及2)每个片段包含的prefs。对于这两个问题,您可以使用不同的资源版本,如您所述,或者您可以实现代码中的差异。

对于问题#1,您可以直接调用loadHeadersFromResource,并具有不同的头文件资源文件,或者您可以使用类似的代码。例如,我的PreferencesActivity为每个prefs部分使用单独的PreferenceFragment子类,并在运行时决定显示哪些片段(标题):

@Override
public void onBuildHeaders(List<Header> targets) {
    // Build a list of PreferenceFragment class objects to show now
    List<Class<? extends PreferenceFragment>> fragmentClasses = ...;

    // Create a Header for each fragment to return to Android
    for (Class<? extends PreferenceFragment> fragmentClass: fragmentClasses) {
        try {
            PreferenceFragment fragment = fragmentClass.newInstance();
            Header header = new Header();
            header.fragment = fragmentClass.getName();
            header.titleRes = fragment.getTitleId();
            targets.add(header);
            this.headers = targets;
        } catch (Exception e) {
        }
    }
}

对于问题#2,您可以从公共资源文件中的首选项开始,然后在代码中添加条件的:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Load common prefs from an XML resource
    addPreferencesFromResource(R.xml.preferences);

    // Add conditional prefs in code
    PreferenceScreen prefScreen = getPreferenceScreen();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        Preference pref = ...; // create condition pref
        prefScreen.addPreference(pref);
    }
}

我实际上在代码中添加了所有prefs,common和conditional。但是,我没有看到从头开始创建PreferenceScreen的方法,所以我实际上有一个空的XML文件,我从资源加载,然后在代码中添加所有首选项。它的效果非常好。