I'm trying to add a support.v4.app.Fragment
to a PreferenceActivity
header, like so:
<header
android:fragment="com.example.SupportFragmentSubClass"
android:title="Selecting this should show the accompanying fragment" >
</header>
This throws a ClassCastException, presumably because the PreferenceActivity is expecting a sub-class of android.app.Fragment
, rather than support.v4.app.Fragment
.
My use case is this:
I have non-standard Fragment that I want to use as a preference on both <3.0 and >3.0 devices. For >=3.0, I need an android.app.Fragment
subclass so it can be embedded in the 'detail pane' of the preferences activity on tablet devices. For <3.0, I need a v4.support.app.Fragment
subclass so I can throw in it an ActivityFragment
.
Is there a workaround that would allow me to use a compatibility Fragment in this situation?
PreferenceFragment
is not in the Android Support package, and you cannot use an Android Support package Fragment class in a PreferenceActivity
this way. Moreover, your headers would not work on Android 2.x anyway, since the PreferenceActivity
in Android 2.x does not know about fragments.
In principle, you could fork the PreferenceActivity
from the source code to create one that does use the Android Support version of Fragment
.
Or, organize your preferences to use fragments on Android 3.0+ and avoid them on Android 2.x. Here is a sample project where I demonstrate a way to do this.
As @CommonsWare points out, it's not possible to what I wanted without rewriting PreferenceActivity, and that looks like a load of work.
The not-so-elegant solution I settled on was to create two PreferenceActivities (as shown here) and also create two Fragment subclasses, one for each flavour of Fragment.
So, PrefsActivityHC
adds this header:
<header
<!-- An android.app.Fragment subclass -->
android:fragment="com.example.project.MyFragmentHC"
</header>
...while PrefsActivity
adds this preference:
<Preference>
<intent
<!-- A v4.support.app.Fragment subclass, wrapped in an ActivityFragment -->
android:targetClass="com.example.project.MyFragmentActivity"
android:targetPackage="com.example.project" >
</intent>
</Preference>
To minimise the amount of code duplication required to have two near-identical fragments, I created a MyFragmentDelegate
class that supports common fragment methods, and held an instance of that in MyFragment
and MyFragmentHC
. Calls to the methods in these fragments are then just forwarded to the delegate:
class MyFragment {
MyFragmentDelegate mDelegate;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return mDelegate.onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
}
}
class MyFragmentHC {
MyFragmentDelegate mDelegate;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return mDelegate.onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With