How do I call a specific PreferenceFragment from a PreferenceActivity?
Asked Answered
T

3

13

I have a PreferenceActivity with several fragments:

R.xml.preferences: (shortened for better readability):

<?xml version="1.0" encoding="utf-8"?>
<preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
    <header android:fragment="fragments.Fragment1" android:id="@+id/fragment1" [...] />
    <header android:fragment="fragments.Fragment2" android:id="@+id/fragment2" [...] />
    [...]
</preference-headers>

SettingsActivity:

public class SettingsActivity extends PreferenceActivity {
    @Override
    public void onBuildHeaders(List<Header> target) {
        loadHeadersFromResource(R.xml.preferences, target);
    }
}

This will show a list entry with fragments.Fragment1, fragments.Fragment2, ... if SettingsActivity is started.

But now I want to pass a Bundle such that a specific PreferenceFragment is opened when starting the activity:

so I added this to SettingsActivity:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (savedInstanceState != null && savedInstanceState.getBoolean("shortcut")) {
        // directly jump to fragments.Fragment1
    }
}

I tried to load the fragment via getFragmentManager().findFragmentById(R.id.fragment1), but this returns null. But even if I had the correct instance, I would not know how to invoke it. Also, calling loadHeadersFromResource(R.xml.preferences_fragment1, target); does not work - This will throw a RuntimeException "XML document must start with tag; foundPreferenceScreen at Binary XML file". I have no ideas left and also a search on SO and Google did not return any relevant results.

So my question is: Is it possible to directly load a PreferenceFragment (e.g. fragments.Fragment1) from the Activitiy's onCreate method? If so, how?

Theodora answered 2/12, 2012 at 18:43 Comment(0)
N
34

According to: http://developer.android.com/reference/android/preference/PreferenceActivity.html#EXTRA_SHOW_FRAGMENT

public static final String EXTRA_SHOW_FRAGMENT

Added in API level 11 When starting this activity, the invoking Intent can contain this extra string to specify which fragment should be initially displayed.

Constant Value: ":android:show_fragment"

intent = new Intent( this, SettingsActivity.class );
intent.putExtra( PreferenceActivity.EXTRA_SHOW_FRAGMENT, Fragment1.class.getName() );
intent.putExtra( PreferenceActivity.EXTRA_NO_HEADERS, true );
Nolpros answered 2/12, 2012 at 18:49 Comment(2)
Really cool they supported this. Thanks for sharing. It worked well for me also.Silsbye
It works. I am also trying to pass request action to that activity by putExtra but Bundle savedInstanceState is always null. Help Please.Dope
G
1

Just use below code in your PreferenceActivity and PreferenceFragment in onCreate

addPreferencesFromResource(R.xml.**YOUR PREFERENCE FRAGMENT XML**);
Grovel answered 19/8, 2014 at 6:33 Comment(0)
T
0

Or use PreferenceActivity.switchToHeader. When starting the PreferenceActivity, the header/overview of all settings pages is loaded first and then the fragment. When finishing the fragment, you will return to the overview.

MyPreferenceActivity:

@Override
public void onBuildHeaders(List<Header> headers) {

    loadHeadersFromResource(R.xml.preference_headers, headers);

    int headerId = getIntent() != null ? getIntent().getIntExtra("header", 0) : 0;
    if (headerId > 0) {
        getIntent().removeExtra("header");
        switchToHeader(findHeaderById(headerId));
    }
}

private Header findHeaderById(long id) {

    if (headers != null)
        for (Header header : headers)
            if (header.id == id) return header;

    return null;
}

This shows how to call the PreferenceActivity together with the fragment in your MainActivity:

Intent intent = new Intent(context, MyPreferenceActivity.class);
intent.putExtra("header", R.id.header1);
intent.putExtra("key", "pref1");
startActivity(intent);

If necessary, you can open the respective preference right away in PreferenceFragment1:

@Override
public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    addPreferencesFromResource(R.xml.preferences_1);  

    String key = getActivity().getIntent() != null ? getActivity().getIntent().getStringExtra("key") : null;

    if (key != null) {
         getActivity().getIntent().removeExtra(key);
         openPreference(key);
    }
}

private void openPreference(String key) {

    PreferenceScreen preferenceScreen = getPreferenceScreen();
    ListAdapter listAdapter = preferenceScreen.getRootAdapter();

    for (int position = 0; position < listAdapter.getCount(); position++) {

        Preference preference = (Preference) listAdapter.getItem(position);

        if (preference.equals(findPreference(key))) {
            preferenceScreen.onItemClick(null, null, position, 0);
            break;
        }
    }
}

preference_headers.xml:

<?xml version="1.0" encoding="utf-8"?>

<preference-headers
    xmlns:android="http://schemas.android.com/apk/res/android">

    <header android:id="@+id/headers1"
        android:fragment="de.almisoft.PreferenceFragment1"
        android:title="Title1"
        android:summary="Summary1">
    </header>

    <header android:id="@+id/headers2"
        android:fragment="de.almisoft.PreferenceFragment2"
        android:title="Title2"
        android:summary="Summary2">
    </header>

</preference-headers>

preferences_1.xml:

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

    <Preference
        android:key="pref1"
        android:title="title"/>

</PreferenceScreen>
Tore answered 26/9, 2019 at 13:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.