I have a Honeycomb style preferences. I define the headers:
<preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
<header android:id="@+id/pref_general" android:fragment="MyPreferencesFragment" android:title="@string/pref_general_title">
<extra android:name="resource" android:value="pref_general" />
</header>
<header android:id="@+id/pref_sharing" android:fragment="MyPreferencesFragment" android:title="@string/pref_sharing_title">
<extra android:name="resource" android:value="pref_sharing" />
</header>
</preference-headers>
Then I load them in PreferenceActivity:
public void onBuildHeaders(List<Header> target)
{
loadHeadersFromResource(R.xml.preference_headers, target);
}
How can I then address exact Fragment by its ID in startPreferenceFragment? How can I access a list item corresponding to that Fragment so I can enable/disable it?
I have found the solution. There is no way to access fragment directly, but it can be found via ListAdapter
. In your PreferenceActivity you can write:
int fragmentId = R.id.pref_sharing;
for (int i = 0; i < getListAdapter().getCount(); i++)
{
Header header = (Header) getListAdapter().getItem(i);
if (fragmentId == header.id)
{
// You can access a fragment name (class)
String fragment = header.fragment;
// You can access fragment arguments
Bundle args = header.fragmentArguments;
}
}
I didn't find a way to disable a header list item but I created a workaround based on this code.
You can access the PreferenceFragment directly. In fact there are probably several ways to do it. I've tried the first one below, and it definitely works. The other two I haven't tried myself but I see no reason why they shouldn't work.
- Override
onAttach()
in your fragment and pass a reference to itself (i.e., this
) to the activity that's passed in. Keep a copy of the reference in the host activity and use it to call any method you want in your fragment directly later on. See here for an example. Credit goes to @Devunwired for this solution.
- Same as (1) but pass the fragment's id to the host activity instead of
this
. You can use getId to get the fragment's id in its onAttach()
method. Then use the regular findFragmentById in your activity to retrieve the fragment when you want it.
- Update a static int variable in your host activity (directly, or via a public method) with the id of the fragment, which you can find using getId in either
onAttach()
or onCreate()
of your fragment. Then use findFragmentById in your activity as before. This involves less coding than (1) or (2) but it is an ugly hack!
It would be good if Android made it easier to access fragments in headers directly though. For a while I couldn't understand why using the android:id
value in the layout XML didn't work with findFragmentById
, until I realised the header is not a fragment!