如何将标头和首选项对象添加到不使用XML文件而是使用Java的PreferenceActivity?

And*_*res 7 android android-preferences android-fragments

我有PreferenceFragment和PreferenceActivity,我通过这种方式从XML文件中添加标题:

PreferenceActivity

@Override
public void onBuildHeaders(List<Header> target) {  
    if(DEBUG) Log.i("PreferenceActivity", "onBuildHeaders() -> LogicAnalizerPrefs");
    if(android.os.Build.VERSION.SDK_INT >= 12) {
        loadHeadersFromResource(R.xml.preference_header_logicanalizer, target);
    }
}
Run Code Online (Sandbox Code Playgroud)

PreferenceFragment:

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

        if(DEBUG) Log.i("PreferenceFragment", "onCreate() -> LogicAnalizerPrefsFragment");
        int res = getActivity().getResources().getIdentifier(getArguments().getString("logicprefsheaders"), "xml", getActivity().getPackageName());
        addPreferencesFromResource(res);
    }
Run Code Online (Sandbox Code Playgroud)

我有标题的XML文件是:

R.xml.preference_header_logicanalizer:

<header
        android:fragment="com.protocolanalyzer.andres.LogicAnalizerPrefsFragment"
        android:icon="@drawable/settings"
        android:title="General" >
        <extra
            android:name="logicprefsheaders"
            android:value="logicgeneral" />
    </header>
    <header
        android:fragment="com.protocolanalyzer.andres.LogicAnalizerPrefsFragment"
        android:icon="@drawable/settings"
        android:title="Canal 1" >
        <extra
            android:name="logicprefsheaders"
            android:value="c1analizerprefs" />
    </header>
    <header
        android:fragment="com.protocolanalyzer.andres.LogicAnalizerPrefsFragment"
        android:icon="@drawable/settings"
        android:title="Canal 2" >
        <extra
            android:name="logicprefsheaders"
            android:value="c2analizerprefs" />
    </header>
    <header
        android:fragment="com.protocolanalyzer.andres.LogicAnalizerPrefsFragment"
        android:icon="@drawable/settings"
        android:title="Canal 3" >
        <extra
            android:name="logicprefsheaders"
            android:value="c3analizerprefs" />
    </header>
    <header
        android:fragment="com.protocolanalyzer.andres.LogicAnalizerPrefsFragment"
        android:icon="@drawable/settings"
        android:title="Canal 4" >
        <extra
            android:name="logicprefsheaders"
            android:value="c4analizerprefs" />
    </header>
Run Code Online (Sandbox Code Playgroud)

这是我的一个xml文件,用于在单击标题时显示其中一个首选项:

c1analizerprefs.xml:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >

    <PreferenceCategory android:title="@string/AnalyzerProtocolTitle1" >
        <ListPreference
            android:defaultValue="0"
            android:entries="@array/protocolList"
            android:entryValues="@array/protocolValues"
            android:key="protocol1"
            android:summary="@string/AnalyzerProtocolSummary"
            android:title="@string/AnalyzerProtocolTitle1" />
        <ListPreference
            android:defaultValue="1"
            android:entries="@array/channelNames"
            android:entryValues="@array/protocolValues"
            android:key="SCL1"
            android:summary="@string/AnalyzerSCLSummary"
            android:title="@string/AnalyzerSCLTitle" />

        <EditTextPreference
            android:defaultValue="9600"
            android:title="@string/AnalyzerBaudTitle"
            android:key="BaudRate1"
            android:summary="@string/AnalyzerBaudSummary"
            android:inputType="number" />
    </PreferenceCategory>

</PreferenceScreen>
Run Code Online (Sandbox Code Playgroud)

因此,在大屏幕我有这个结果如预期,我只用一个PreferenceFragment加我4头.

但我在XML中定义的四个首选项如c1analizerprefs.xml几乎相同,唯一的变化是一个数字(例如:Pref.1,Pref.2,...)所以我想在Java中添加它们以便我可以使用a for()添加4个或更多首选项,轻松更改重复次数,因为文本总是相同我只更改数字所以这样我不需要为每个首选项创建一个XML文件,我动态创建它们在Java中.

如何在Java中添加首选项而不是使用XML文件?在PreferenceFragment中,我只有addPreferencesFromResource()或addPreferencesFromIntent().有没有办法添加首选项对象?

goo*_*all 6

以防万一有人正在寻找一些代码......

以下示例从XML加载一些标头,然后以编程方式附加到它们.

第一个覆盖onBuildHeaders您的内部PreferenceActivity:

@Override
public void onBuildHeaders(List<Header> target) {
    loadHeadersFromResource(R.xml.preference_headers, target);

    // Add layer as a new settings header
    Header header = new Header();
    header.title = "More Settings";
    header.summary = "Change even more settings";
    header.fragment = SettingsFragment.class.getName();

    Bundle b = new Bundle();
    b.putString("category", "MoreSettings");
    header.fragmentArguments = b;
    target.add(header);
}
Run Code Online (Sandbox Code Playgroud)

然后覆盖onHeaderClick您的内部PreferenceActivity.请注意,您将标头的fragmentArguments传递给片段,以便您可以检测单击了哪个标头(类别):

@Override
public void onHeaderClick(Header header, int position) {    
    this.startPreferencePanel(SettingsFragment.class.getName(), header.fragmentArguments, header.titleRes, header.title, null, 0);
}
Run Code Online (Sandbox Code Playgroud)

然后在PreferenceFragment覆盖onCreate中:

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

    if (savedInstanceState == null) {
        mCategory = getArguments().getString("category");
    }
    else {
        // Orientation Change
        mCategory = savedInstanceState.getString("category");
    }

    if (mCategory.equals("Map")) {
        // Load the preferences from an XML resource
        addPreferencesFromResource(R.xml.preferences_map);
    }
    if (mCategory.equals("MoreSettings")) {
        // Load the preferences from an XML resource
        PreferenceScreen preferenceScreen = getPreferenceManager().createPreferenceScreen(getActivity());
        // add prefrences using preferenceScreen.addPreference()
        this.setPreferenceScreen(preferenceScreen);
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您想查看预定义标头的xml.

RES/XML/preference_headers.xml

<?xml version="1.0" encoding="utf-8"?>
<preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
    <header 
        android:fragment="com.appName.fragments.SettingsFragment"
        android:title="@string/pref_category_map_title"
        android:summary="@string/pref_category_map_sum" >
        <!-- key/value pairs can be included as arguments for the fragment. -->
        <extra android:name="category" android:value="Map" />
    </header>
</preference-headers>
Run Code Online (Sandbox Code Playgroud)

RES/XML/preferences_map.xml

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <CheckBoxPreference
        android:key="pref_zoomToCurrentLocationOnStart"
        android:title="@string/pref_zoomToCurrentLocationOnStart_title"
        android:summary="@string/pref_zoomToCurrentLocationOnStart_sum"
        android:defaultValue="true" />
    <CheckBoxPreference
        android:key="pref_myLocation"
        android:title="@string/pref_myLocation_title"
        android:summary="@string/pref_myLocation_sum"
        android:defaultValue="true" />
</PreferenceScreen>
Run Code Online (Sandbox Code Playgroud)


Jev*_*vll 4

动态添加标头并不容易。正如 android 文档所述:

Blockquote 典型的实现将使用 loadHeadersFromResource(int, List) 从资源填充列表。

如果您仍然想使用动态解决方案,您可能需要查看 loadHeadersFromResource 的源代码(例如,此处http://grepcode.com/file/repository.grepcode.com/java/ext/com .google.android/android/4.0.1_r1/android/preference/PreferenceActivity.java#PreferenceActivity.loadHeadersFromResource(int%2Cjava.util.List) )

总结,

  1. 您需要创建一个 PreferenceActivity.Header 对象,

  2. 通过设置其各种属性来准备使用,这些属性可以在文档中找到:http://developer.android.com/reference/android/preference/PreferenceActivity.Header.html

  3. 最后将创建的标头添加到列表中:(target.add(header);目标是传递给 onBuildHeaders 的参数)