NOTICE: Please save yourself some time and refer to the accepted answer, no need to read all the quesiton.
You may read the rest of the question and the
If you are on the latest ADT plugin, there is an option to easily create a preference Activity that supports most older Android versions as well as all the new ones.
Right click on your project -> Other -> Android Activity
Then choose SettingsActivity
The Activity created will take take care of working with both high and low API versions since it uses if statements to choose the appropriate method of displaying the preferences.
EDIT
A good point was brought up: Phone-Sized devices, regardless of API version use the old PreferenceActivity
methods.
The quickest way to get API 11+ devices to use Fragments
is to remove !isXLargeTablet(context);
from isSimplePreferences()
private static boolean isSimplePreferences(Context context) {
return ALWAYS_SIMPLE_PREFS
|| Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB;
}
However, now the user has more navigation to do.
This is because onBuildHeaders()
is called.
To get rid of this, we will need to make our own PreferenceFragment that adds each xml resource.
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public static class AllPreferencesFragment extends PreferenceFragment{
@Override
public void onCreate (Bundle savedInstanceState){
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.pref_general);
// Add 'notifications' preferences, and a corresponding header.
PreferenceCategory fakeHeader = new PreferenceCategory(getActivity());
fakeHeader.setTitle(R.string.pref_header_notifications);
getPreferenceScreen().addPreference(fakeHeader);
addPreferencesFromResource(R.xml.pref_notification);
// Add 'data and sync' preferences, and a corresponding header.
fakeHeader = new PreferenceCategory(getActivity());
fakeHeader.setTitle(R.string.pref_header_data_sync);
getPreferenceScreen().addPreference(fakeHeader);
addPreferencesFromResource(R.xml.pref_data_sync);
// Bind the summaries of EditText/List/Dialog/Ringtone preferences to
// their values. When their values change, their summaries are updated
// to reflect the new value, per the Android Design guidelines.
bindPreferenceSummaryToValue(findPreference("example_text"));
bindPreferenceSummaryToValue(findPreference("example_list"));
bindPreferenceSummaryToValue(findPreference("notifications_new_message_ringtone"));
bindPreferenceSummaryToValue(findPreference("sync_frequency"));
}
}
If you can determine the screen size from outside the Activity
that launches the settings, you can specify a fragment for it to launch via EXTRA_SHOW_FRAGMENT
i.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT, "com.example.test.SettingsActivity$AllPreferencesFragment");
Or you can have the SettingsActivity
determine whether or not to show this Fragment (assuming you're happy with the isXLargeTablet()
method.
Change onBuildHeaders()
to:
@Override
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void onBuildHeaders(List target) {
if (!isSimplePreferences(this) && isXLargeTablet(this)) {
loadHeadersFromResource(R.xml.pref_headers, target);
}
}
Add this method:
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void setupNewApiPhoneSizePreferences() {
if (!isXLargeTablet(this) && Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB){
getFragmentManager().beginTransaction().replace(android.R.id.content, new AllPreferencesFragment()).commit();
}
}
And in onPostCreate()
add the method call.
setupNewApiPhoneSizePreferences();
This should now use non-deprecated calls from API 11 onwards.