PreferenceActivity , PreferenceFragment and headers (Part 2)
In previous post we described how to use Preference Activity and Preference Fragment.
Android 3.0 (API Level 11) introduced Preference Headers through which we can show the user the list of headers, and upon clicking on a header, show the fragment.
A great benefit to using this design is that PreferenceActivity automatically presents the two-pane layout when running on large screens.
This behavior is particularly useful if you have more than 10 preferences, otherwise I suggest the direction of displaying headers all of the time.
Scenario 3: Preference Headers
If we investigate the source code to PreferenceActivity , we will see that the logic that drives the single-pane vs. dual-pane UI decision boils down to:
At present, it will be true for -sw720dp devices, false otherwise.
For your curiosity in Nexus7 is false.
If you want to use ActionBarSherlock library is very simple to modify our code.
In this example we use a Fragment for each entry in preference headers. We can reuse the same subclass of PreferenceFragment for each group and use an extra argument to specify which preferences XML file the fragment should load. We can see code here:
In the next scenario we try to use Preference Header with all devices, not only with android 3.0 or higher.
You can find the next post here
You can get code from GitHub:
Android 3.0 (API Level 11) introduced Preference Headers through which we can show the user the list of headers, and upon clicking on a header, show the fragment.
A great benefit to using this design is that PreferenceActivity automatically presents the two-pane layout when running on large screens.
This behavior is particularly useful if you have more than 10 preferences, otherwise I suggest the direction of displaying headers all of the time.
Scenario 3: Preference Headers
- Step 1: Define the preferences_headers_scenario3.xml
This file lists each settings group and declares which fragment contains the corresponding list of settings.The file is placed in the res\xml folder.
With the android:fragment attribute, each header declares an instance of PreferenceFragment that should open when the user selects the header. - Step 2: Create the Preference Activity
To display the preference headers, you must implement the onBuildHeaders() callback method and call loadHeadersFromResource(). For example:
This Activity will only show the list of headers.public class PreferencesActivityScenario3 extends PreferenceActivity { /** * Populate the activity with the top-level headers. */ @Override public void onBuildHeaders(List target) { loadHeadersFromResource(R.xml.preference_headers_scenario3, target); } }
Like all Activities, the Preference Activity must be included in the application manifest: - Step 3: Create the Preference Fragment
public class UpdatePreferenceFragment extends PreferenceFragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.preference_update); } }
To display the application settings hosted in this Activity, open it by calling startActivity or startActivityForResult:Intent i = new Intent(this, PreferencesActivityScenario3.class); startActivityForResult(i, SHOW_PREFERENCES);
When using preference headers, your subclass of PreferenceActivity doesn't need to implement the onCreate() method, because the only required task for the activity is to load the headers.
And that’s all! Just execute the app in Android emulator or real device and see following output.
Single-pane layout with headers:
Dual-pane layout with headers:
If we investigate the source code to PreferenceActivity , we will see that the logic that drives the single-pane vs. dual-pane UI decision boils down to:
/** * Called to determine if the activity should run in multi-pane mode. * The default implementation returns true if the screen is large * enough. */ public boolean onIsMultiPane() { boolean preferMultiPane = getResources().getBoolean( com.android.internal.R.bool.preferences_prefer_dual_pane); return preferMultiPane; }The Resource
com.android.internal.R.bool.preferences_prefer_dual_pane
has different definitions based upon screen size.At present, it will be true for -sw720dp devices, false otherwise.
For your curiosity in Nexus7 is false.
If you want to use ActionBarSherlock library is very simple to modify our code.
public class PreferencesActivityABSScenario3 extends SherlockPreferenceActivity { /** * Populate the activity with the top-level headers. */ @Override public void onBuildHeaders(List target) { loadHeadersFromResource(R.xml.preference_headers_scenario3, target); } }
In this example we use a Fragment for each entry in preference headers. We can reuse the same subclass of PreferenceFragment for each group and use an extra argument to specify which preferences XML file the fragment should load. We can see code here:
- Step 1: Define the preferences_headers2_scenario3.xml
In this case we use a GenericPreferenceFragment for each header, and we use The extras element to pass key-value pairs to the fragment in a Bundle.
- Step 2: Create the Preference Activity
We can use the same Activity see above. - Step 2: Create the GenericPreferenceFragment
public class GenericePreferenceFragment extends PreferenceFragment { @Override public void onCreate(Bundle savedInstanceState) { int preferenceFile_toLoad=-1; String settings = getArguments().getString("settings"); if (Constants.SETTING_UPDATE.equals(settings)) { // Load the preferences from an XML resource preferenceFile_toLoad= R.xml.preference_update; }else if (Constants.SETTING_DISPLAY.equals(settings)) { // Load the preferences from an XML resource preferenceFile_toLoad=R.xml.preference_display; }else if (Constants.SETTING_NOTIFY.equals(settings)) { // Load the preferences from an XML resource preferenceFile_toLoad=R.xml.preference_notify; } addPreferencesFromResource(preferenceFile_toLoad); } }
In the next scenario we try to use Preference Header with all devices, not only with android 3.0 or higher.
You can find the next post here
You can get code from GitHub:
Thank you. Your tutorial helped me out a great deal.
ReplyDeleteCould you do one on AccountManager in the future?