Search code examples
androidandroid-fragmentsandroid-preferences

How to add a Header and Preference Object to PreferenceActivity not using an XML file but Java?


I have PreferenceFragment and a PreferenceActivity from which I add headers from a XML file on this way:

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);
    }
}

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);
    }

And the XML file where I have the headers is:

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>

And this is one of my xml files which is used to display one of the preferences when a Header is clicked:

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>

So in a large screen I have this result as expected and I use only one PreferenceFragment to add my 4 headers.

But my four Preferences defined in the XML like c1analizerprefs.xml are almost the same the only change is a number (For example: Pref. 1, Pref. 2, ...) so I want to add them in Java so I can use a for() to add 4 or more Preferences easily changing the number of repetitions because the text is always the same I only change a number so on this way I don't need to create one XML file for each preference, I create them dynamically in Java.

How can I add a Preference to a Header in Java instead of using a XML file? In PreferenceFragment I only have addPreferencesFromResource() or addPreferencesFromIntent(). Is any way to add a Preference Object?


Solution

  • Adding headers dynamically will not be easy. As android documentation states:

    Blockquote Typical implementations will use loadHeadersFromResource(int, List) to fill in the list from a resource.

    If you still want to go with a dynamic solution, you might want to take a look at the source code of loadHeadersFromResource (for example, here 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) )

    To sum up,

    1. you need to create a PreferenceActivity.Header object,

    2. prepare it for usage by setting its various properties that can be found in documentation: http://developer.android.com/reference/android/preference/PreferenceActivity.Header.html,

    3. and finally add that created header to the list: target.add(header); (target is the argument that is passed to onBuildHeaders)