diff options
| author | Dianne Hackborn <hackbod@google.com> | 2010-08-03 13:07:11 -0700 |
|---|---|---|
| committer | Dianne Hackborn <hackbod@google.com> | 2010-08-03 17:07:45 -0700 |
| commit | b3cf10ffa8ff9cac0da8b23a0d84076b3f501400 (patch) | |
| tree | a5e396aabb0ae5b52bd6c9df7cbccb0350e7a16e /core | |
| parent | 6c8687cf1e52abede549908afe8d8820d24eaecd (diff) | |
| download | frameworks_base-b3cf10ffa8ff9cac0da8b23a0d84076b3f501400.zip frameworks_base-b3cf10ffa8ff9cac0da8b23a0d84076b3f501400.tar.gz frameworks_base-b3cf10ffa8ff9cac0da8b23a0d84076b3f501400.tar.bz2 | |
Add facility to switch to new fragments from preferences.
Change-Id: I009315b59cf81b4962e9c5a4490f0f82743ed64a
Diffstat (limited to 'core')
| -rw-r--r-- | core/java/android/app/Activity.java | 9 | ||||
| -rw-r--r-- | core/java/android/app/FragmentManager.java | 45 | ||||
| -rw-r--r-- | core/java/android/preference/Preference.java | 24 | ||||
| -rw-r--r-- | core/java/android/preference/PreferenceActivity.java | 37 | ||||
| -rw-r--r-- | core/java/android/preference/PreferenceFragment.java | 30 | ||||
| -rw-r--r-- | core/java/android/preference/PreferenceScreen.java | 2 | ||||
| -rwxr-xr-x | core/res/res/values/attrs.xml | 3 |
7 files changed, 127 insertions, 23 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 9beaec0..e3351b0 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -2055,9 +2055,10 @@ public class Activity extends ContextThemeWrapper /** * Flag for {@link #popBackStack(String, int)} * and {@link #popBackStack(int, int)}: If set, and the name or ID of - * a back stack entry has been supplied, then that entry will also be - * removed. Otherwise, all entries up to but not including that entry - * will be removed + * a back stack entry has been supplied, then all matching entries will + * be consumed until one that doesn't match is found or the bottom of + * the stack is reached. Otherwise, all entries up to but not including that entry + * will be removed. */ public static final int POP_BACK_STACK_INCLUSIVE = 1<<0; @@ -2066,7 +2067,7 @@ public class Activity extends ContextThemeWrapper * to pop, else false. */ public boolean popBackStack() { - return popBackStack(null, 0); + return popBackStack(null, -1); } /** diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java index c0e757d..2054e2a 100644 --- a/core/java/android/app/FragmentManager.java +++ b/core/java/android/app/FragmentManager.java @@ -629,7 +629,7 @@ public class FragmentManager { if (mBackStack == null) { return false; } - if (name == null && id < 0) { + if (name == null && id < 0 && (flags&Activity.POP_BACK_STACK_INCLUSIVE) == 0) { int last = mBackStack.size()-1; if (last < 0) { return false; @@ -644,22 +644,37 @@ public class FragmentManager { } }); } else { - int index = mBackStack.size()-1; - while (index >= 0) { - BackStackEntry bss = mBackStack.get(index); - if (name != null && name.equals(bss.getName())) { - break; + int index = -1; + if (name != null || id >= 0) { + // If a name or ID is specified, look for that place in + // the stack. + index = mBackStack.size()-1; + while (index >= 0) { + BackStackEntry bss = mBackStack.get(index); + if (name != null && name.equals(bss.getName())) { + break; + } + if (id >= 0 && id == bss.mIndex) { + break; + } + index--; } - if (id >= 0 && id == bss.mIndex) { - break; + if (index < 0) { + return false; + } + if ((flags&Activity.POP_BACK_STACK_INCLUSIVE) != 0) { + index--; + // Consume all following entries that match. + while (index >= 0) { + BackStackEntry bss = mBackStack.get(index); + if ((name != null && name.equals(bss.getName())) + || (id >= 0 && id == bss.mIndex)) { + index--; + continue; + } + break; + } } - index--; - } - if (index < 0) { - return false; - } - if ((flags&Activity.POP_BACK_STACK_INCLUSIVE) != 0) { - index--; } if (index == mBackStack.size()-1) { return false; diff --git a/core/java/android/preference/Preference.java b/core/java/android/preference/Preference.java index 381f794..117e507 100644 --- a/core/java/android/preference/Preference.java +++ b/core/java/android/preference/Preference.java @@ -56,6 +56,7 @@ import java.util.Set; * @attr ref android.R.styleable#Preference_title * @attr ref android.R.styleable#Preference_summary * @attr ref android.R.styleable#Preference_order + * @attr ref android.R.styleable#Preference_fragment * @attr ref android.R.styleable#Preference_layout * @attr ref android.R.styleable#Preference_widgetLayout * @attr ref android.R.styleable#Preference_enabled @@ -88,6 +89,7 @@ public class Preference implements Comparable<Preference>, OnDependencyChangeLis private CharSequence mSummary; private String mKey; private Intent mIntent; + private String mFragment; private boolean mEnabled = true; private boolean mSelectable = true; private boolean mRequiresKey; @@ -210,6 +212,10 @@ public class Preference implements Comparable<Preference>, OnDependencyChangeLis mOrder = a.getInt(attr, mOrder); break; + case com.android.internal.R.styleable.Preference_fragment: + mFragment = a.getString(attr); + break; + case com.android.internal.R.styleable.Preference_layout: mLayoutResId = a.getResourceId(attr, mLayoutResId); break; @@ -315,6 +321,24 @@ public class Preference implements Comparable<Preference>, OnDependencyChangeLis } /** + * Sets the class name of a fragment to be shown when this Preference is clicked. + * + * @param fragment The class name of the fragment associated with this Preference. + */ + public void setFragment(String fragment) { + mFragment = fragment; + } + + /** + * Return the fragment class name associated with this Preference. + * + * @return The fragment class name last set via {@link #setFragment} or XML. + */ + public String getFragment() { + return mFragment; + } + + /** * Sets the layout resource that is inflated as the {@link View} to be shown * for this Preference. In most cases, the default layout is sufficient for * custom Preference objects and only the widget layout needs to be changed. diff --git a/core/java/android/preference/PreferenceActivity.java b/core/java/android/preference/PreferenceActivity.java index fdc874b..e13c3e8 100644 --- a/core/java/android/preference/PreferenceActivity.java +++ b/core/java/android/preference/PreferenceActivity.java @@ -93,11 +93,22 @@ import java.util.List; * * {@sample development/samples/ApiDemos/res/xml/preference_headers.xml headers} * - * See {@link PreferenceFragment} for information on implementing the + * <p>The first header is shown by Prefs1Fragment, which populates itself + * from the following XML resource:</p> + * + * {@sample development/samples/ApiDemos/res/xml/fragmented_preferences.xml preferences} + * + * <p>Note that this XML resource contains a preference screen holding another + * fragment, the Prefs1FragmentInner implemented here. This allows the user + * to traverse down a hierarchy of preferences; pressing back will pop each + * fragment off the stack to return to the previous preferences. + * + * <p>See {@link PreferenceFragment} for information on implementing the * fragments themselves. */ public abstract class PreferenceActivity extends ListActivity implements - PreferenceManager.OnPreferenceTreeClickListener { + PreferenceManager.OnPreferenceTreeClickListener, + PreferenceFragment.OnPreferenceStartFragmentCallback { private static final String TAG = "PreferenceActivity"; private static final String PREFERENCES_TAG = "android:preferences"; @@ -106,6 +117,8 @@ public abstract class PreferenceActivity extends ListActivity implements private static final String EXTRA_PREFS_NO_HEADERS = ":android:no_headers"; + private static final String BACK_STACK_PREFS = ":android:prefs"; + // extras that allow any preference activity to be launched as part of a wizard // show Back and Next buttons? takes boolean parameter @@ -206,16 +219,19 @@ public abstract class PreferenceActivity extends ListActivity implements public static class Header { /** * Title of the header that is shown to the user. + * @attr ref android.R.styleable#PreferenceHeader_title */ CharSequence title; /** * Optional summary describing what this header controls. + * @attr ref android.R.styleable#PreferenceHeader_summary */ CharSequence summary; /** * Optional icon resource to show for this header. + * @attr ref android.R.styleable#PreferenceHeader_icon */ int iconRes; @@ -228,6 +244,7 @@ public abstract class PreferenceActivity extends ListActivity implements /** * Full class name of the fragment to display when this header is * selected. + * @attr ref android.R.styleable#PreferenceHeader_fragment */ String fragment; } @@ -551,6 +568,8 @@ public abstract class PreferenceActivity extends ListActivity implements * @param fragmentName The name of the fragment to display. */ public void switchToHeader(String fragmentName) { + popBackStack(BACK_STACK_PREFS, POP_BACK_STACK_INCLUSIVE); + Fragment f; try { f = Fragment.instantiate(this, fragmentName); @@ -561,6 +580,20 @@ public abstract class PreferenceActivity extends ListActivity implements openFragmentTransaction().replace(com.android.internal.R.id.prefs, f).commit(); } + @Override + public boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref) { + Fragment f; + try { + f = Fragment.instantiate(this, pref.getFragment()); + } catch (Exception e) { + Log.w(TAG, "Failure instantiating fragment " + pref.getFragment(), e); + return false; + } + openFragmentTransaction().replace(com.android.internal.R.id.prefs, f) + .addToBackStack(BACK_STACK_PREFS).commit(); + return true; + } + /** * Posts a message to bind the preferences to the list view. * <p> diff --git a/core/java/android/preference/PreferenceFragment.java b/core/java/android/preference/PreferenceFragment.java index ac61574..a5395e2 100644 --- a/core/java/android/preference/PreferenceFragment.java +++ b/core/java/android/preference/PreferenceFragment.java @@ -125,6 +125,21 @@ public abstract class PreferenceFragment extends Fragment implements } }; + /** + * Interface that PreferenceFragment's containing activity should + * implement to be able to process preference items that wish to + * switch to a new fragment. + */ + public interface OnPreferenceStartFragmentCallback { + /** + * Called when the user has clicked on a Preference that has + * a fragment class name associated with it. The implementation + * to should instantiate and switch to an instance of the given + * fragment. + */ + boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref); + } + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -168,6 +183,13 @@ public abstract class PreferenceFragment extends Fragment implements } @Override + public void onDestroyView() { + mList = null; + mHandler.removeCallbacks(mRequestFocus); + super.onDestroyView(); + } + + @Override public void onDestroy() { super.onDestroy(); mPreferenceManager.dispatchActivityDestroy(); @@ -251,7 +273,13 @@ public abstract class PreferenceFragment extends Fragment implements /** * {@inheritDoc} */ - public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { + public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, + Preference preference) { + if (preference.getFragment() != null && + getActivity() instanceof OnPreferenceStartFragmentCallback) { + return ((OnPreferenceStartFragmentCallback)getActivity()).onPreferenceStartFragment( + this, preference); + } return false; } diff --git a/core/java/android/preference/PreferenceScreen.java b/core/java/android/preference/PreferenceScreen.java index 95e5432..f34f4a3 100644 --- a/core/java/android/preference/PreferenceScreen.java +++ b/core/java/android/preference/PreferenceScreen.java @@ -136,7 +136,7 @@ public final class PreferenceScreen extends PreferenceGroup implements AdapterVi @Override protected void onClick() { - if (getIntent() != null || getPreferenceCount() == 0) { + if (getIntent() != null || getFragment() != null || getPreferenceCount() == 0) { return; } diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 728f999..97c5822 100755 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -3457,6 +3457,9 @@ <!-- The order for the Preference (lower values are to be ordered first). If this is not specified, the default orderin will be alphabetic. --> <attr name="order" format="integer" /> + <!-- When used inside of a modern PreferenceActivity, this declares + a new PreferenceFragment to be shown when the user selects this item. --> + <attr name="fragment" /> <!-- The layout for the Preference in a PreferenceActivity screen. This should rarely need to be changed, look at widgetLayout instead. --> <attr name="layout" /> |
