summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2010-08-03 13:07:11 -0700
committerDianne Hackborn <hackbod@google.com>2010-08-03 17:07:45 -0700
commitb3cf10ffa8ff9cac0da8b23a0d84076b3f501400 (patch)
treea5e396aabb0ae5b52bd6c9df7cbccb0350e7a16e /core
parent6c8687cf1e52abede549908afe8d8820d24eaecd (diff)
downloadframeworks_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.java9
-rw-r--r--core/java/android/app/FragmentManager.java45
-rw-r--r--core/java/android/preference/Preference.java24
-rw-r--r--core/java/android/preference/PreferenceActivity.java37
-rw-r--r--core/java/android/preference/PreferenceFragment.java30
-rw-r--r--core/java/android/preference/PreferenceScreen.java2
-rwxr-xr-xcore/res/res/values/attrs.xml3
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" />