Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 669
Andres Avatar asked Apr 01 '13 18:04

Andres


1 Answers

Just in case someone is actually looking for some code...

The following example loads some headers from XML and then appends to them programatically.

1st override onBuildHeaders inside your 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);
}

Then override onHeaderClick inside your PreferenceActivity. Note that you pass the header's fragmentArguments to the fragment so you can detect which header was clicked (category):

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

Then inside your PreferenceFragment override 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);
    }
}

In case you want to see the xml for predefined headers.

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>

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>
like image 174
dwp4ge Avatar answered Sep 20 '22 19:09

dwp4ge