Was Preferencefragment Intentionally Excluded from the Compatibility Package

Was PreferenceFragment intentionally excluded from the compatibility package?

Discovering that PreferenceActivity contains deprecated methods (although these are used in the accompanying sample code)

The deprecated methods are deprecated as of Android 3.0. They are perfectly fine on all versions of Android, but the direction is to use PreferenceFragment on Android 3.0 and higher.

Can anyone tell me whether this was intentional?

My guess is it's a question of engineering time, but that's just a guess.

If so, can I easily target a range of devices (i.e. < 3.0 and >=3.0) or will I have to jump through hoops?

I consider it to be done "easily". Have two separate PreferenceActivity implementations, one using preference headers and PreferenceFragments, the other using the original approach. Choose the right one at the point you need to (e.g., when the user clicks on the options menu item). Here is a sample project demonstrating this. Or, have a single PreferenceActivity that handles both cases, as in this sample project.

If it wasn't intentionally excluded, can we expect a new release of the compatibility package?

You will find out when the rest of us find out, which is to say, if and when it ships.

Or is there another workaround that is safe to use?

See above.

Building Compatibility PreferenceFragment on Android

Look at Fr4gg0r's implementation of PreferenceFragment using reflex at
http://forum.xda-developers.com/showthread.php?t=1363906

PreferenceFragment alternative for the Android compatibility API?

See the latest revision of the v7 support library, which introduced a PreferenceFragmentCompat.

PreferenceActivity Android 4.0 and earlier

PreferenceFragment will not work on 2.2 and 2.3 (only API level 11 and above). If you want to offer the best user experience and still support older Android versions, the best practice here seems to be to implement two PreferenceActivity classes and to decide at runtime which one to invoke. However, this method still includes calling deprecated APIs, but you can't avoid that.

So for instance, you have a preference_headers.xml:

<preference-headers xmlns:android="http://schemas.android.com/apk/res/android" > 
<header android:fragment="your.package.PrefsFragment"
android:title="...">
<extra android:name="resource" android:value="preferences" />
</header>
</preference-headers>

and a standard preferences.xml (which hasn't changed much since lower API levels):

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" android:title="...">
...
</PreferenceScreen>

Then you need an implementation of PreferenceFragment:

public static class PrefsFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
}

And finally, you need two implementations of PreferenceActivity, for API levels supporting or not supporting PreferenceFragments:

public class PreferencesActivity extends PreferenceActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
addPreferencesFromResource(R.xml.other);
}
}

and:

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

At the point where you want to display the preference screen to the user, you decide which one to start:

if (Build.VERSION.SDK_INT < 11) {
startActivity(new Intent(this, PreferencesActivity.class));
} else {
startActivity(new Intent(this, OtherPreferencesActivity.class));
}

So basically, you have an xml file per fragment, you load each of these xml files manually for API levels < 11, and both Activities use the same preferences.

How can I show a preferences screen on older Android devices i.e. Gingerbread and Froyo?

Neither ActionBarSherlock nor the Android Support Library provides support for Preference Fragments.

You need to revert to Perference Activities as explained in the Settings Documentation.

There are a few old questions that discuss the same topic:

  • PreferenceActivity Android 4.0 and earlier
  • Was PreferenceFragment intentionally excluded from the compatibility package?

SwitchPreference in PreferenceFragment is resetting values

Turns out this is actually a google bug.

Issue reported here

Alternatives to PreferenceFragment with android-support-v4

UPDATE - 6/11/2015

Support-v7 library now includes PreferenceFragmentCompat. So it will be a better idea to use it.


Add the following project as a library project to your application.

https://github.com/kolavar/android-support-v4-preferencefragment

You can keep everything including your fragment transaction as it is. When importing the PreferenceFragment class, make sure the correct import header is user.

import android.support.v4.preference.PreferenceFragment;

instead of

import android.preference.PreferenceFragment;


Related Topics



Leave a reply



Submit