From 8eb2e244f9b14d946ee587d0b673b866865026c0 Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Mon, 1 Nov 2010 12:31:24 -0700 Subject: Various PreferenceActivity and related improvement. This is all about making the preferences implementation better. Well, mostly all about that. Change-Id: I8efa98cb5680f3ccfa3ed694a1586de3fb3a9e11 --- core/java/android/app/Fragment.java | 10 ++ core/java/android/app/FragmentBreadCrumbs.java | 2 + core/java/android/app/FragmentManager.java | 18 ++++ .../android/preference/PreferenceActivity.java | 106 ++++++++++++++++----- core/java/android/view/WindowManager.java | 48 ++++++++-- core/res/res/anim/fragment_close_enter.xml | 2 +- core/res/res/anim/fragment_close_exit.xml | 2 +- core/res/res/anim/fragment_open_enter.xml | 2 +- core/res/res/anim/fragment_open_exit.xml | 2 +- 9 files changed, 159 insertions(+), 33 deletions(-) (limited to 'core') diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java index f27a15e..eaf1aee 100644 --- a/core/java/android/app/Fragment.java +++ b/core/java/android/app/Fragment.java @@ -1027,6 +1027,16 @@ public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener } /** + * Called when this fragment's option menu items are no longer being + * included in the overall options menu. Receiving this call means that + * the menu needed to be rebuilt, but this fragment's items were not + * included in the newly built menu (its {@link #onCreateOptionsMenu(Menu, MenuInflater)} + * was not called). + */ + public void onDestroyOptionsMenu() { + } + + /** * This hook is called whenever an item in your options menu is selected. * The default implementation simply returns false to have the normal * processing happen (calling the item's Runnable or sending a message to diff --git a/core/java/android/app/FragmentBreadCrumbs.java b/core/java/android/app/FragmentBreadCrumbs.java index 22e0747..e924c1c 100644 --- a/core/java/android/app/FragmentBreadCrumbs.java +++ b/core/java/android/app/FragmentBreadCrumbs.java @@ -16,6 +16,7 @@ package android.app; +import android.animation.LayoutTransition; import android.app.FragmentManager.BackStackEntry; import android.content.Context; import android.util.AttributeSet; @@ -69,6 +70,7 @@ public class FragmentBreadCrumbs extends ViewGroup addView(mContainer); a.getFragmentManager().addOnBackStackChangedListener(this); updateCrumbs(); + setLayoutTransition(new LayoutTransition()); } /** diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java index 45f9325..512ca16 100644 --- a/core/java/android/app/FragmentManager.java +++ b/core/java/android/app/FragmentManager.java @@ -268,6 +268,7 @@ final class FragmentManagerImpl implements FragmentManager { ArrayList mAdded; ArrayList mAvailIndices; ArrayList mBackStack; + ArrayList mCreatedMenus; // Must be accessed while locked. ArrayList mBackStackIndices; @@ -1325,15 +1326,32 @@ final class FragmentManagerImpl implements FragmentManager { public boolean dispatchCreateOptionsMenu(Menu menu, MenuInflater inflater) { boolean show = false; + ArrayList newMenus = null; if (mActive != null) { for (int i=0; i(); + } + newMenus.add(f); } } } + + if (mCreatedMenus != null) { + for (int i=0; i from) { @@ -982,7 +993,7 @@ public abstract class PreferenceActivity extends ListActivity implements */ public void startPreferenceFragment(Fragment fragment, boolean push) { FragmentTransaction transaction = getFragmentManager().openTransaction(); - startPreferenceFragment(fragment, transaction); + transaction.replace(com.android.internal.R.id.prefs, fragment); if (push) { transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); transaction.addToBackStack(BACK_STACK_PREFS); @@ -993,25 +1004,74 @@ public abstract class PreferenceActivity extends ListActivity implements } /** - * Start a new fragment. - * - * @param fragment The fragment to start - * @param ft The FragmentTransaction in which to perform this operation. - * Will not be added to the back stack or committed for you; you use do that. + * Start a new fragment containing a preference panel. If the prefences + * are being displayed in multi-pane mode, the given fragment class will + * be instantiated and placed in the appropriate pane. If running in + * single-pane mode, a new activity will be launched in which to show the + * fragment. + * + * @param fragmentClass Full name of the class implementing the fragment. + * @param args Any desired arguments to supply to the fragment. + * @param titleRes Optional resource identifier of the title of this + * fragment. + * @param titleText Optional text of the title of this fragment. + * @param resultTo Optional fragment that result data should be sent to. + * If non-null, resultTo.onActivityResult() will be called when this + * preference panel is done. The launched panel must use + * {@link #finishPreferencePanel(Fragment, int, Intent)} when done. + * @param resultRequestCode If resultTo is non-null, this is the caller's + * request code to be received with the resut. */ - public void startPreferenceFragment(Fragment fragment, FragmentTransaction ft) { - ft.replace(com.android.internal.R.id.prefs, fragment); + public void startPreferencePanel(String fragmentClass, Bundle args, int titleRes, + CharSequence titleText, Fragment resultTo, int resultRequestCode) { + if (mSinglePane) { + startWithFragment(fragmentClass, args, resultTo, resultRequestCode); + } else { + Fragment f = Fragment.instantiate(this, fragmentClass, args); + if (resultTo != null) { + f.setTargetFragment(resultTo, resultRequestCode); + } + FragmentTransaction transaction = getFragmentManager().openTransaction(); + transaction.replace(com.android.internal.R.id.prefs, f); + if (titleRes != 0) { + transaction.setBreadCrumbTitle(titleRes); + } else if (titleText != null) { + transaction.setBreadCrumbTitle(titleText); + } + transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); + transaction.addToBackStack(BACK_STACK_PREFS); + transaction.commit(); + } } - + + /** + * Called by a preference panel fragment to finish itself. + * + * @param caller The fragment that is asking to be finished. + * @param resultCode Optional result code to send back to the original + * launching fragment. + * @param resultData Optional result data to send back to the original + * launching fragment. + */ + public void finishPreferencePanel(Fragment caller, int resultCode, Intent resultData) { + if (mSinglePane) { + setResult(resultCode, resultData); + finish(); + } else { + if (caller != null) { + if (caller.getTargetFragment() != null) { + caller.getTargetFragment().onActivityResult(caller.getTargetRequestCode(), + resultCode, resultData); + } + } + // XXX be smarter about popping the stack. + onBackPressed(); + } + } + @Override public boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref) { - Fragment f = Fragment.instantiate(this, pref.getFragment(), pref.getExtras()); - FragmentTransaction transaction = getFragmentManager().openTransaction(); - startPreferenceFragment(f, transaction); - transaction.setBreadCrumbTitle(pref.getTitle()); - transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); - transaction.addToBackStack(BACK_STACK_PREFS); - transaction.commit(); + startPreferencePanel(pref.getFragment(), pref.getExtras(), 0, pref.getTitle(), null, 0); return true; } diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index e5f4b08..c657a1c 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -794,7 +794,17 @@ public interface WindowManager extends ViewManager { public int softInputMode; /** - * Placement of window within the screen as per {@link Gravity} + * Placement of window within the screen as per {@link Gravity}. Both + * {@link Gravity#apply(int, int, int, android.graphics.Rect, int, int, + * android.graphics.Rect) Gravity.apply} and + * {@link Gravity#applyDisplay(int, android.graphics.Rect, android.graphics.Rect) + * Gravity.applyDisplay} are used during window layout, with this value + * given as the desired gravity. For example you can specify + * {@link Gravity#DISPLAY_CLIP_HORIZONTAL Gravity.DISPLAY_CLIP_HORIZONTAL} and + * {@link Gravity#DISPLAY_CLIP_VERTICAL Gravity.DISPLAY_CLIP_VERTICAL} here + * to control the behavior of + * {@link Gravity#applyDisplay(int, android.graphics.Rect, android.graphics.Rect) + * Gravity.applyDisplay}. * * @see Gravity */ @@ -802,13 +812,19 @@ public interface WindowManager extends ViewManager { /** * The horizontal margin, as a percentage of the container's width, - * between the container and the widget. + * between the container and the widget. See + * {@link Gravity#apply(int, int, int, android.graphics.Rect, int, int, + * android.graphics.Rect) Gravity.apply} for how this is used. This + * field is added with {@link #x} to supply the xAdj parameter. */ public float horizontalMargin; /** * The vertical margin, as a percentage of the container's height, - * between the container and the widget. + * between the container and the widget. See + * {@link Gravity#apply(int, int, int, android.graphics.Rect, int, int, + * android.graphics.Rect) Gravity.apply} for how this is used. This + * field is added with {@link #y} to supply the yAdj parameter. */ public float verticalMargin; @@ -1168,14 +1184,22 @@ public interface WindowManager extends ViewManager { sb.append('x'); sb.append((height== MATCH_PARENT ?"fill":(height==WRAP_CONTENT?"wrap":height))); sb.append(")"); - if (softInputMode != 0) { - sb.append(" sim=#"); - sb.append(Integer.toHexString(softInputMode)); + if (horizontalMargin != 0) { + sb.append(" hm="); + sb.append(horizontalMargin); + } + if (verticalMargin != 0) { + sb.append(" vm="); + sb.append(verticalMargin); } if (gravity != 0) { sb.append(" gr=#"); sb.append(Integer.toHexString(gravity)); } + if (softInputMode != 0) { + sb.append(" sim=#"); + sb.append(Integer.toHexString(softInputMode)); + } sb.append(" ty="); sb.append(type); sb.append(" fl=#"); @@ -1190,6 +1214,18 @@ public interface WindowManager extends ViewManager { sb.append(" or="); sb.append(screenOrientation); } + if (alpha != 1.0f) { + sb.append(" alpha="); + sb.append(alpha); + } + if (screenBrightness != BRIGHTNESS_OVERRIDE_NONE) { + sb.append(" sbrt="); + sb.append(screenBrightness); + } + if (buttonBrightness != BRIGHTNESS_OVERRIDE_NONE) { + sb.append(" bbrt="); + sb.append(buttonBrightness); + } if ((flags & FLAG_COMPATIBLE_WINDOW) != 0) { sb.append(" compatible=true"); } diff --git a/core/res/res/anim/fragment_close_enter.xml b/core/res/res/anim/fragment_close_enter.xml index 7a9a3b9..edf1948 100644 --- a/core/res/res/anim/fragment_close_enter.xml +++ b/core/res/res/anim/fragment_close_enter.xml @@ -26,7 +26,7 @@ android:duration="@android:integer/config_mediumAnimTime"/> diff --git a/core/res/res/anim/fragment_open_enter.xml b/core/res/res/anim/fragment_open_enter.xml index ac60494..334f4ef 100644 --- a/core/res/res/anim/fragment_open_enter.xml +++ b/core/res/res/anim/fragment_open_enter.xml @@ -24,7 +24,7 @@ android:propertyName="alpha" android:duration="@android:integer/config_mediumAnimTime"/> -- cgit v1.1