Loading api/current.xml +245 −1 Original line number Diff line number Diff line Loading @@ -16410,6 +16410,17 @@ visibility="public" > </field> <field name="Theme_Dialog_NoFrame" type="int" transient="false" volatile="false" value="16973972" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> <field name="Theme_InputMethod" type="int" transient="false" Loading Loading @@ -21390,8 +21401,36 @@ deprecated="not deprecated" visibility="public" > </method> <method name="popBackStack" return="boolean" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > <parameter name="name" type="java.lang.String"> </parameter> <parameter name="flags" type="int"> </parameter> </method> <method name="popBackStack" return="boolean" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > <parameter name="id" type="int"> </parameter> <parameter name="flags" type="int"> </parameter> </method> <method name="registerForContextMenu" return="void" Loading Loading @@ -25835,6 +25874,211 @@ </parameter> </method> </class> <class name="DialogFragment" extends="android.app.Fragment" abstract="false" static="false" final="false" deprecated="not deprecated" visibility="public" > <implements name="android.content.DialogInterface.OnCancelListener"> </implements> <implements name="android.content.DialogInterface.OnDismissListener"> </implements> <constructor name="DialogFragment" type="android.app.DialogFragment" static="false" final="false" deprecated="not deprecated" visibility="public" > </constructor> <constructor name="DialogFragment" type="android.app.DialogFragment" static="false" final="false" deprecated="not deprecated" visibility="public" > <parameter name="style" type="int"> </parameter> <parameter name="theme" type="int"> </parameter> </constructor> <method name="dismiss" return="void" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > </method> <method name="getCancelable" return="boolean" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > </method> <method name="getDialog" return="android.app.Dialog" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > </method> <method name="getTheme" return="int" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > </method> <method name="onCancel" return="void" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > <parameter name="dialog" type="android.content.DialogInterface"> </parameter> </method> <method name="onCreateDialog" return="android.app.Dialog" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > <parameter name="savedInstanceState" type="android.os.Bundle"> </parameter> </method> <method name="onDismiss" return="void" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > <parameter name="dialog" type="android.content.DialogInterface"> </parameter> </method> <method name="setCancelable" return="void" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > <parameter name="cancelable" type="boolean"> </parameter> </method> <method name="show" return="void" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > <parameter name="activity" type="android.app.Activity"> </parameter> <parameter name="tag" type="java.lang.String"> </parameter> </method> <method name="show" return="int" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > <parameter name="activity" type="android.app.Activity"> </parameter> <parameter name="transaction" type="android.app.FragmentTransaction"> </parameter> <parameter name="tag" type="java.lang.String"> </parameter> </method> <field name="STYLE_NORMAL" type="int" transient="false" volatile="false" value="0" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> <field name="STYLE_NO_FRAME" type="int" transient="false" volatile="false" value="2" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> <field name="STYLE_NO_INPUT" type="int" transient="false" volatile="false" value="3" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> <field name="STYLE_NO_TITLE" type="int" transient="false" volatile="false" value="1" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> </class> <class name="ExpandableListActivity" extends="android.app.Activity" abstract="false" Loading Loading @@ -26615,7 +26859,7 @@ </parameter> </method> <method name="commit" return="void" return="int" abstract="true" native="false" synchronized="false" core/java/android/app/Activity.java +38 −5 Original line number Diff line number Diff line Loading @@ -2053,15 +2053,48 @@ public class Activity extends ContextThemeWrapper return false; } /** * 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 */ static final int POP_BACK_STACK_INCLUSIVE = 1<<0; /** * Pop the top state off the back stack. Returns true if there was one * to pop, else false. */ public boolean popBackStack() { return popBackStack(null, 0); } /** * Pop the last fragment transition from the local activity's fragment * back stack. If there is nothing to pop, false is returned. * @param name If non-null, this is the name of a previous back state * to look for; if found, all states up to (but not including) that * state will be popped. If null, only the top state is popped. * to look for; if found, all states up to that state will be popped. The * {@link #POP_BACK_STACK_INCLUSIVE} flag can be used to control whether * the named state itself is popped. If null, only the top state is popped. * @param flags Either 0 or {@link #POP_BACK_STACK_INCLUSIVE}. */ public boolean popBackStack(String name, int flags) { return mFragments.popBackStackState(mHandler, name, flags); } /** * Pop all back stack states up to the one with the given identifier. * @param id Identifier of the stated to be popped. If no identifier exists, * false is returned. * The identifier is the number returned by * {@link FragmentTransaction#commit() FragmentTransaction.commit()}. The * {@link #POP_BACK_STACK_INCLUSIVE} flag can be used to control whether * the named state itself is popped. * @param flags Either 0 or {@link #POP_BACK_STACK_INCLUSIVE}. */ public boolean popBackStack(String name) { return mFragments.popBackStackState(mHandler, name); public boolean popBackStack(int id, int flags) { return mFragments.popBackStackState(mHandler, id, flags); } /** Loading @@ -2070,7 +2103,7 @@ public class Activity extends ContextThemeWrapper * but you can override this to do whatever you want. */ public void onBackPressed() { if (!popBackStack(null)) { if (!popBackStack()) { finish(); } } Loading core/java/android/app/BackStackEntry.java +24 −1 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ final class BackStackState implements Parcelable { final int mTransition; final int mTransitionStyle; final String mName; final int mIndex; public BackStackState(FragmentManager fm, BackStackEntry bse) { int numRemoved = 0; Loading Loading @@ -58,6 +59,7 @@ final class BackStackState implements Parcelable { mTransition = bse.mTransition; mTransitionStyle = bse.mTransitionStyle; mName = bse.mName; mIndex = bse.mIndex; } public BackStackState(Parcel in) { Loading @@ -65,6 +67,7 @@ final class BackStackState implements Parcelable { mTransition = in.readInt(); mTransitionStyle = in.readInt(); mName = in.readString(); mIndex = in.readInt(); } public BackStackEntry instantiate(FragmentManager fm) { Loading @@ -90,6 +93,7 @@ final class BackStackState implements Parcelable { bse.mTransition = mTransition; bse.mTransitionStyle = mTransitionStyle; bse.mName = mName; bse.mIndex = mIndex; return bse; } Loading @@ -102,6 +106,7 @@ final class BackStackState implements Parcelable { dest.writeInt(mTransition); dest.writeInt(mTransitionStyle); dest.writeString(mName); dest.writeInt(mIndex); } public static final Parcelable.Creator<BackStackState> CREATOR Loading Loading @@ -151,6 +156,7 @@ final class BackStackEntry implements FragmentTransaction, Runnable { boolean mAddToBackStack; String mName; boolean mCommitted; int mIndex; public BackStackEntry(FragmentManager manager) { mManager = manager; Loading Loading @@ -289,16 +295,28 @@ final class BackStackEntry implements FragmentTransaction, Runnable { return this; } public void commit() { public int commit() { if (mCommitted) throw new IllegalStateException("commit already called"); if (FragmentManager.DEBUG) Log.v(TAG, "Commit: " + this); mCommitted = true; if (mAddToBackStack) { mIndex = mManager.allocBackStackIndex(this); } else { mIndex = -1; } mManager.enqueueAction(this); return mIndex; } public void run() { if (FragmentManager.DEBUG) Log.v(TAG, "Run: " + this); if (mAddToBackStack) { if (mIndex < 0) { throw new IllegalStateException("addToBackStack() called after commit()"); } } Op op = mHead; while (op != null) { switch (op.cmd) { Loading Loading @@ -450,6 +468,11 @@ final class BackStackEntry implements FragmentTransaction, Runnable { mManager.mActivity.invalidateOptionsMenu(); mManager.mNeedMenuInvalidate = false; } if (mIndex >= 0) { mManager.freeBackStackIndex(mIndex); mIndex = -1; } } public String getName() { Loading core/java/android/app/DialogFragment.java 0 → 100644 +277 −0 Original line number Diff line number Diff line /* * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.app; import android.content.DialogInterface; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; /** * A fragment that displays a dialog window, floating on top of its * activity's window. This fragment contains a Dialog object, which it * displays as appropriate based on the fragment's state. Control of * the dialog (deciding when to show, hide, dismiss it) should be done through * the API here, not with direct calls on the dialog. * * <p>Implementations should override this class and implement * {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)} to supply the * content of the dialog. Alternatively, they can override * {@link #onCreateDialog(Bundle)} to create an entirely custom dialog, such * as an AlertDialog, with its own content. */ public class DialogFragment extends Fragment implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener { /** * Style for {@link #DialogFragment(int, int)} constructor: a basic, * normal dialog. */ public static final int STYLE_NORMAL = 0; /** * Style for {@link #DialogFragment(int, int)} constructor: don't include * a title area. */ public static final int STYLE_NO_TITLE = 1; /** * Style for {@link #DialogFragment(int, int)} constructor: don't draw * any frame at all; the view hierarchy returned by {@link #onCreateView} * is entirely responsible for drawing the dialog. */ public static final int STYLE_NO_FRAME = 2; /** * Style for {@link #DialogFragment(int, int)} constructor: like * {@link #STYLE_NO_FRAME}, but also disables all input to the dialog. * The user can not touch it, and its window will not receive input focus. */ public static final int STYLE_NO_INPUT = 3; private static final String SAVED_DIALOG_STATE_TAG = "android:savedDialogState"; private static final String SAVED_STYLE = "android:style"; private static final String SAVED_THEME = "android:theme"; private static final String SAVED_CANCELABLE = "android:cancelable"; private static final String SAVED_BACK_STACK_ID = "android:backStackId"; int mStyle = STYLE_NORMAL; int mTheme = 0; boolean mCancelable = true; int mBackStackId = -1; Dialog mDialog; boolean mDestroyed; public DialogFragment() { } /** * Constructor to customize the basic appearance and behavior of the * fragment's dialog. This can be used for some common dialog behaviors, * taking care of selecting flags, theme, and other options for you. The * same effect can be achieve by manually setting Dialog and Window * attributes yourself. * * @param style Selects a standard style: may be {@link #STYLE_NORMAL}, * {@link #STYLE_NO_TITLE}, {@link #STYLE_NO_FRAME}, or * {@link #STYLE_NO_INPUT}. * @param theme Optional custom theme. If 0, an appropriate theme (based * on the style) will be selected for you. */ public DialogFragment(int style, int theme) { mStyle = style; if (mStyle == STYLE_NO_FRAME || mStyle == STYLE_NO_INPUT) { mTheme = android.R.style.Theme_Dialog_NoFrame; } if (theme != 0) { mTheme = theme; } } /** * Display the dialog, adding the fragment to the given activity. This * is a convenience for explicitly creating a transaction, adding the * fragment to it with the given tag, and committing it. This does * <em>not</em> add the transaction to the back stack. When the fragment * is dismissed, a new transaction will be executed to remove it from * the activity. * @param activity The activity this fragment will be added to. * @param tag The tag for this fragment, as per * {@link FragmentTransaction#add(Fragment, String) FragmentTransaction.add}. */ public void show(Activity activity, String tag) { FragmentTransaction ft = activity.openFragmentTransaction(); ft.add(this, tag); ft.commit(); } /** * Display the dialog, adding the fragment to the given activity using * an existing transaction and then committing the transaction. * @param activity The activity this fragment will be added to. * @param transaction An existing transaction in which to add the fragment. * @param tag The tag for this fragment, as per * {@link FragmentTransaction#add(Fragment, String) FragmentTransaction.add}. * @return Returns the identifier of the committed transaction, as per * {@link FragmentTransaction#commit() FragmentTransaction.commit()}. */ public int show(Activity activity, FragmentTransaction transaction, String tag) { transaction.add(this, tag); mBackStackId = transaction.commit(); return mBackStackId; } /** * Dismiss the fragment and its dialog. If the fragment was added to the * back stack, all back stack state up to and including this entry will * be popped. Otherwise, a new transaction will be committed to remove * the fragment. */ public void dismiss() { if (mDialog != null) { mDialog.dismiss(); } if (mBackStackId >= 0) { getActivity().popBackStack(mBackStackId, Activity.POP_BACK_STACK_INCLUSIVE); mBackStackId = -1; } else { FragmentTransaction ft = getActivity().openFragmentTransaction(); ft.remove(this); ft.commit(); } } public Dialog getDialog() { return mDialog; } public int getTheme() { return mTheme; } public void setCancelable(boolean cancelable) { mCancelable = cancelable; if (mDialog != null) mDialog.setCancelable(cancelable); } public boolean getCancelable() { return mCancelable; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState != null) { mStyle = savedInstanceState.getInt(SAVED_STYLE, mStyle); mTheme = savedInstanceState.getInt(SAVED_THEME, mTheme); mCancelable = savedInstanceState.getBoolean(SAVED_CANCELABLE, mCancelable); mBackStackId = savedInstanceState.getInt(SAVED_BACK_STACK_ID, mBackStackId); } } public Dialog onCreateDialog(Bundle savedInstanceState) { return new Dialog(getActivity(), getTheme()); } public void onCancel(DialogInterface dialog) { if (mBackStackId >= 0) { // If this fragment is part of the back stack, then cancelling // the dialog means popping off the back stack. getActivity().popBackStack(mBackStackId, Activity.POP_BACK_STACK_INCLUSIVE); mBackStackId = -1; } } public void onDismiss(DialogInterface dialog) { } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); mDialog = onCreateDialog(savedInstanceState); mDestroyed = false; switch (mStyle) { case STYLE_NO_INPUT: mDialog.getWindow().addFlags( WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); // fall through... case STYLE_NO_FRAME: case STYLE_NO_TITLE: mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE); } View view = getView(); if (view != null) { if (view.getParent() != null) { throw new IllegalStateException("DialogFragment can not be attached to a container view"); } mDialog.setContentView(view); } mDialog.setOwnerActivity(getActivity()); mDialog.setCancelable(mCancelable); mDialog.setOnCancelListener(this); mDialog.setOnDismissListener(this); if (savedInstanceState != null) { Bundle dialogState = savedInstanceState.getBundle(SAVED_DIALOG_STATE_TAG); if (dialogState != null) { mDialog.onRestoreInstanceState(dialogState); } } } @Override public void onStart() { super.onStart(); mDialog.show(); } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); if (mDialog != null) { Bundle dialogState = mDialog.onSaveInstanceState(); if (dialogState != null) { outState.putBundle(SAVED_DIALOG_STATE_TAG, dialogState); } } outState.putInt(SAVED_STYLE, mStyle); outState.putInt(SAVED_THEME, mTheme); outState.putBoolean(SAVED_CANCELABLE, mCancelable); outState.putInt(SAVED_BACK_STACK_ID, mBackStackId); } @Override public void onStop() { super.onStop(); mDialog.hide(); } /** * Detach from list view. */ @Override public void onDestroyView() { super.onDestroyView(); mDestroyed = true; mDialog.dismiss(); mDialog = null; } } core/java/android/app/FragmentManager.java +88 −4 Original line number Diff line number Diff line Loading @@ -86,6 +86,10 @@ public class FragmentManager { ArrayList<Integer> mAvailIndices; ArrayList<BackStackEntry> mBackStack; // Must be accessed while locked. ArrayList<BackStackEntry> mBackStackIndices; ArrayList<Integer> mAvailBackStackIndices; int mCurState = Fragment.INITIALIZING; Activity mActivity; Loading Loading @@ -514,6 +518,62 @@ public class FragmentManager { } } public int allocBackStackIndex(BackStackEntry bse) { synchronized (this) { if (mAvailBackStackIndices == null || mAvailBackStackIndices.size() <= 0) { if (mBackStackIndices == null) { mBackStackIndices = new ArrayList<BackStackEntry>(); } int index = mBackStackIndices.size(); if (DEBUG) Log.v(TAG, "Setting back stack index " + index + " to " + bse); mBackStackIndices.add(bse); return index; } else { int index = mAvailBackStackIndices.remove(mAvailBackStackIndices.size()-1); if (DEBUG) Log.v(TAG, "Adding back stack index " + index + " with " + bse); mBackStackIndices.set(index, bse); return index; } } } public void setBackStackIndex(int index, BackStackEntry bse) { synchronized (this) { if (mBackStackIndices == null) { mBackStackIndices = new ArrayList<BackStackEntry>(); } int N = mBackStackIndices.size(); if (index < N) { if (DEBUG) Log.v(TAG, "Setting back stack index " + index + " to " + bse); mBackStackIndices.set(index, bse); } else { while (N < index) { mBackStackIndices.add(null); if (mAvailBackStackIndices == null) { mAvailBackStackIndices = new ArrayList<Integer>(); } if (DEBUG) Log.v(TAG, "Adding available back stack index " + N); mAvailBackStackIndices.add(N); N++; } if (DEBUG) Log.v(TAG, "Adding back stack index " + index + " with " + bse); mBackStackIndices.add(bse); } } } public void freeBackStackIndex(int index) { synchronized (this) { mBackStackIndices.set(index, null); if (mAvailBackStackIndices == null) { mAvailBackStackIndices = new ArrayList<Integer>(); } if (DEBUG) Log.v(TAG, "Freeing back stack index " + index); mAvailBackStackIndices.add(index); } } /** * Only call from main thread! */ Loading Loading @@ -554,11 +614,22 @@ public class FragmentManager { mBackStack.add(state); } public boolean popBackStackState(Handler handler, String name) { public boolean popBackStackState(Handler handler, String name, int flags) { return popBackStackState(handler, name, -1, flags); } public boolean popBackStackState(Handler handler, int id, int flags) { if (id < 0) { return false; } return popBackStackState(handler, null, id, flags); } boolean popBackStackState(Handler handler, String name, int id, int flags) { if (mBackStack == null) { return false; } if (name == null) { if (name == null && id < 0) { int last = mBackStack.size()-1; if (last < 0) { return false; Loading @@ -576,11 +647,21 @@ public class FragmentManager { int index = mBackStack.size()-1; while (index >= 0) { BackStackEntry bss = mBackStack.get(index); if (name.equals(bss.getName())) { if (name != null && name.equals(bss.getName())) { break; } if (id >= 0 && id == bss.mIndex) { break; } index--; } if (index < 0 || index == mBackStack.size()-1) { if (index < 0) { return false; } if ((flags&Activity.POP_BACK_STACK_INCLUSIVE) != 0) { index--; } if (index == mBackStack.size()-1) { return false; } final ArrayList<BackStackEntry> states Loading Loading @@ -772,6 +853,9 @@ public class FragmentManager { for (int i=0; i<fms.mBackStack.length; i++) { BackStackEntry bse = fms.mBackStack[i].instantiate(this); mBackStack.add(bse); if (bse.mIndex >= 0) { setBackStackIndex(bse.mIndex, bse); } } } else { mBackStack = null; Loading Loading
api/current.xml +245 −1 Original line number Diff line number Diff line Loading @@ -16410,6 +16410,17 @@ visibility="public" > </field> <field name="Theme_Dialog_NoFrame" type="int" transient="false" volatile="false" value="16973972" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> <field name="Theme_InputMethod" type="int" transient="false" Loading Loading @@ -21390,8 +21401,36 @@ deprecated="not deprecated" visibility="public" > </method> <method name="popBackStack" return="boolean" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > <parameter name="name" type="java.lang.String"> </parameter> <parameter name="flags" type="int"> </parameter> </method> <method name="popBackStack" return="boolean" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > <parameter name="id" type="int"> </parameter> <parameter name="flags" type="int"> </parameter> </method> <method name="registerForContextMenu" return="void" Loading Loading @@ -25835,6 +25874,211 @@ </parameter> </method> </class> <class name="DialogFragment" extends="android.app.Fragment" abstract="false" static="false" final="false" deprecated="not deprecated" visibility="public" > <implements name="android.content.DialogInterface.OnCancelListener"> </implements> <implements name="android.content.DialogInterface.OnDismissListener"> </implements> <constructor name="DialogFragment" type="android.app.DialogFragment" static="false" final="false" deprecated="not deprecated" visibility="public" > </constructor> <constructor name="DialogFragment" type="android.app.DialogFragment" static="false" final="false" deprecated="not deprecated" visibility="public" > <parameter name="style" type="int"> </parameter> <parameter name="theme" type="int"> </parameter> </constructor> <method name="dismiss" return="void" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > </method> <method name="getCancelable" return="boolean" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > </method> <method name="getDialog" return="android.app.Dialog" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > </method> <method name="getTheme" return="int" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > </method> <method name="onCancel" return="void" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > <parameter name="dialog" type="android.content.DialogInterface"> </parameter> </method> <method name="onCreateDialog" return="android.app.Dialog" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > <parameter name="savedInstanceState" type="android.os.Bundle"> </parameter> </method> <method name="onDismiss" return="void" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > <parameter name="dialog" type="android.content.DialogInterface"> </parameter> </method> <method name="setCancelable" return="void" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > <parameter name="cancelable" type="boolean"> </parameter> </method> <method name="show" return="void" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > <parameter name="activity" type="android.app.Activity"> </parameter> <parameter name="tag" type="java.lang.String"> </parameter> </method> <method name="show" return="int" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > <parameter name="activity" type="android.app.Activity"> </parameter> <parameter name="transaction" type="android.app.FragmentTransaction"> </parameter> <parameter name="tag" type="java.lang.String"> </parameter> </method> <field name="STYLE_NORMAL" type="int" transient="false" volatile="false" value="0" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> <field name="STYLE_NO_FRAME" type="int" transient="false" volatile="false" value="2" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> <field name="STYLE_NO_INPUT" type="int" transient="false" volatile="false" value="3" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> <field name="STYLE_NO_TITLE" type="int" transient="false" volatile="false" value="1" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> </class> <class name="ExpandableListActivity" extends="android.app.Activity" abstract="false" Loading Loading @@ -26615,7 +26859,7 @@ </parameter> </method> <method name="commit" return="void" return="int" abstract="true" native="false" synchronized="false"
core/java/android/app/Activity.java +38 −5 Original line number Diff line number Diff line Loading @@ -2053,15 +2053,48 @@ public class Activity extends ContextThemeWrapper return false; } /** * 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 */ static final int POP_BACK_STACK_INCLUSIVE = 1<<0; /** * Pop the top state off the back stack. Returns true if there was one * to pop, else false. */ public boolean popBackStack() { return popBackStack(null, 0); } /** * Pop the last fragment transition from the local activity's fragment * back stack. If there is nothing to pop, false is returned. * @param name If non-null, this is the name of a previous back state * to look for; if found, all states up to (but not including) that * state will be popped. If null, only the top state is popped. * to look for; if found, all states up to that state will be popped. The * {@link #POP_BACK_STACK_INCLUSIVE} flag can be used to control whether * the named state itself is popped. If null, only the top state is popped. * @param flags Either 0 or {@link #POP_BACK_STACK_INCLUSIVE}. */ public boolean popBackStack(String name, int flags) { return mFragments.popBackStackState(mHandler, name, flags); } /** * Pop all back stack states up to the one with the given identifier. * @param id Identifier of the stated to be popped. If no identifier exists, * false is returned. * The identifier is the number returned by * {@link FragmentTransaction#commit() FragmentTransaction.commit()}. The * {@link #POP_BACK_STACK_INCLUSIVE} flag can be used to control whether * the named state itself is popped. * @param flags Either 0 or {@link #POP_BACK_STACK_INCLUSIVE}. */ public boolean popBackStack(String name) { return mFragments.popBackStackState(mHandler, name); public boolean popBackStack(int id, int flags) { return mFragments.popBackStackState(mHandler, id, flags); } /** Loading @@ -2070,7 +2103,7 @@ public class Activity extends ContextThemeWrapper * but you can override this to do whatever you want. */ public void onBackPressed() { if (!popBackStack(null)) { if (!popBackStack()) { finish(); } } Loading
core/java/android/app/BackStackEntry.java +24 −1 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ final class BackStackState implements Parcelable { final int mTransition; final int mTransitionStyle; final String mName; final int mIndex; public BackStackState(FragmentManager fm, BackStackEntry bse) { int numRemoved = 0; Loading Loading @@ -58,6 +59,7 @@ final class BackStackState implements Parcelable { mTransition = bse.mTransition; mTransitionStyle = bse.mTransitionStyle; mName = bse.mName; mIndex = bse.mIndex; } public BackStackState(Parcel in) { Loading @@ -65,6 +67,7 @@ final class BackStackState implements Parcelable { mTransition = in.readInt(); mTransitionStyle = in.readInt(); mName = in.readString(); mIndex = in.readInt(); } public BackStackEntry instantiate(FragmentManager fm) { Loading @@ -90,6 +93,7 @@ final class BackStackState implements Parcelable { bse.mTransition = mTransition; bse.mTransitionStyle = mTransitionStyle; bse.mName = mName; bse.mIndex = mIndex; return bse; } Loading @@ -102,6 +106,7 @@ final class BackStackState implements Parcelable { dest.writeInt(mTransition); dest.writeInt(mTransitionStyle); dest.writeString(mName); dest.writeInt(mIndex); } public static final Parcelable.Creator<BackStackState> CREATOR Loading Loading @@ -151,6 +156,7 @@ final class BackStackEntry implements FragmentTransaction, Runnable { boolean mAddToBackStack; String mName; boolean mCommitted; int mIndex; public BackStackEntry(FragmentManager manager) { mManager = manager; Loading Loading @@ -289,16 +295,28 @@ final class BackStackEntry implements FragmentTransaction, Runnable { return this; } public void commit() { public int commit() { if (mCommitted) throw new IllegalStateException("commit already called"); if (FragmentManager.DEBUG) Log.v(TAG, "Commit: " + this); mCommitted = true; if (mAddToBackStack) { mIndex = mManager.allocBackStackIndex(this); } else { mIndex = -1; } mManager.enqueueAction(this); return mIndex; } public void run() { if (FragmentManager.DEBUG) Log.v(TAG, "Run: " + this); if (mAddToBackStack) { if (mIndex < 0) { throw new IllegalStateException("addToBackStack() called after commit()"); } } Op op = mHead; while (op != null) { switch (op.cmd) { Loading Loading @@ -450,6 +468,11 @@ final class BackStackEntry implements FragmentTransaction, Runnable { mManager.mActivity.invalidateOptionsMenu(); mManager.mNeedMenuInvalidate = false; } if (mIndex >= 0) { mManager.freeBackStackIndex(mIndex); mIndex = -1; } } public String getName() { Loading
core/java/android/app/DialogFragment.java 0 → 100644 +277 −0 Original line number Diff line number Diff line /* * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.app; import android.content.DialogInterface; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; /** * A fragment that displays a dialog window, floating on top of its * activity's window. This fragment contains a Dialog object, which it * displays as appropriate based on the fragment's state. Control of * the dialog (deciding when to show, hide, dismiss it) should be done through * the API here, not with direct calls on the dialog. * * <p>Implementations should override this class and implement * {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)} to supply the * content of the dialog. Alternatively, they can override * {@link #onCreateDialog(Bundle)} to create an entirely custom dialog, such * as an AlertDialog, with its own content. */ public class DialogFragment extends Fragment implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener { /** * Style for {@link #DialogFragment(int, int)} constructor: a basic, * normal dialog. */ public static final int STYLE_NORMAL = 0; /** * Style for {@link #DialogFragment(int, int)} constructor: don't include * a title area. */ public static final int STYLE_NO_TITLE = 1; /** * Style for {@link #DialogFragment(int, int)} constructor: don't draw * any frame at all; the view hierarchy returned by {@link #onCreateView} * is entirely responsible for drawing the dialog. */ public static final int STYLE_NO_FRAME = 2; /** * Style for {@link #DialogFragment(int, int)} constructor: like * {@link #STYLE_NO_FRAME}, but also disables all input to the dialog. * The user can not touch it, and its window will not receive input focus. */ public static final int STYLE_NO_INPUT = 3; private static final String SAVED_DIALOG_STATE_TAG = "android:savedDialogState"; private static final String SAVED_STYLE = "android:style"; private static final String SAVED_THEME = "android:theme"; private static final String SAVED_CANCELABLE = "android:cancelable"; private static final String SAVED_BACK_STACK_ID = "android:backStackId"; int mStyle = STYLE_NORMAL; int mTheme = 0; boolean mCancelable = true; int mBackStackId = -1; Dialog mDialog; boolean mDestroyed; public DialogFragment() { } /** * Constructor to customize the basic appearance and behavior of the * fragment's dialog. This can be used for some common dialog behaviors, * taking care of selecting flags, theme, and other options for you. The * same effect can be achieve by manually setting Dialog and Window * attributes yourself. * * @param style Selects a standard style: may be {@link #STYLE_NORMAL}, * {@link #STYLE_NO_TITLE}, {@link #STYLE_NO_FRAME}, or * {@link #STYLE_NO_INPUT}. * @param theme Optional custom theme. If 0, an appropriate theme (based * on the style) will be selected for you. */ public DialogFragment(int style, int theme) { mStyle = style; if (mStyle == STYLE_NO_FRAME || mStyle == STYLE_NO_INPUT) { mTheme = android.R.style.Theme_Dialog_NoFrame; } if (theme != 0) { mTheme = theme; } } /** * Display the dialog, adding the fragment to the given activity. This * is a convenience for explicitly creating a transaction, adding the * fragment to it with the given tag, and committing it. This does * <em>not</em> add the transaction to the back stack. When the fragment * is dismissed, a new transaction will be executed to remove it from * the activity. * @param activity The activity this fragment will be added to. * @param tag The tag for this fragment, as per * {@link FragmentTransaction#add(Fragment, String) FragmentTransaction.add}. */ public void show(Activity activity, String tag) { FragmentTransaction ft = activity.openFragmentTransaction(); ft.add(this, tag); ft.commit(); } /** * Display the dialog, adding the fragment to the given activity using * an existing transaction and then committing the transaction. * @param activity The activity this fragment will be added to. * @param transaction An existing transaction in which to add the fragment. * @param tag The tag for this fragment, as per * {@link FragmentTransaction#add(Fragment, String) FragmentTransaction.add}. * @return Returns the identifier of the committed transaction, as per * {@link FragmentTransaction#commit() FragmentTransaction.commit()}. */ public int show(Activity activity, FragmentTransaction transaction, String tag) { transaction.add(this, tag); mBackStackId = transaction.commit(); return mBackStackId; } /** * Dismiss the fragment and its dialog. If the fragment was added to the * back stack, all back stack state up to and including this entry will * be popped. Otherwise, a new transaction will be committed to remove * the fragment. */ public void dismiss() { if (mDialog != null) { mDialog.dismiss(); } if (mBackStackId >= 0) { getActivity().popBackStack(mBackStackId, Activity.POP_BACK_STACK_INCLUSIVE); mBackStackId = -1; } else { FragmentTransaction ft = getActivity().openFragmentTransaction(); ft.remove(this); ft.commit(); } } public Dialog getDialog() { return mDialog; } public int getTheme() { return mTheme; } public void setCancelable(boolean cancelable) { mCancelable = cancelable; if (mDialog != null) mDialog.setCancelable(cancelable); } public boolean getCancelable() { return mCancelable; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState != null) { mStyle = savedInstanceState.getInt(SAVED_STYLE, mStyle); mTheme = savedInstanceState.getInt(SAVED_THEME, mTheme); mCancelable = savedInstanceState.getBoolean(SAVED_CANCELABLE, mCancelable); mBackStackId = savedInstanceState.getInt(SAVED_BACK_STACK_ID, mBackStackId); } } public Dialog onCreateDialog(Bundle savedInstanceState) { return new Dialog(getActivity(), getTheme()); } public void onCancel(DialogInterface dialog) { if (mBackStackId >= 0) { // If this fragment is part of the back stack, then cancelling // the dialog means popping off the back stack. getActivity().popBackStack(mBackStackId, Activity.POP_BACK_STACK_INCLUSIVE); mBackStackId = -1; } } public void onDismiss(DialogInterface dialog) { } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); mDialog = onCreateDialog(savedInstanceState); mDestroyed = false; switch (mStyle) { case STYLE_NO_INPUT: mDialog.getWindow().addFlags( WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); // fall through... case STYLE_NO_FRAME: case STYLE_NO_TITLE: mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE); } View view = getView(); if (view != null) { if (view.getParent() != null) { throw new IllegalStateException("DialogFragment can not be attached to a container view"); } mDialog.setContentView(view); } mDialog.setOwnerActivity(getActivity()); mDialog.setCancelable(mCancelable); mDialog.setOnCancelListener(this); mDialog.setOnDismissListener(this); if (savedInstanceState != null) { Bundle dialogState = savedInstanceState.getBundle(SAVED_DIALOG_STATE_TAG); if (dialogState != null) { mDialog.onRestoreInstanceState(dialogState); } } } @Override public void onStart() { super.onStart(); mDialog.show(); } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); if (mDialog != null) { Bundle dialogState = mDialog.onSaveInstanceState(); if (dialogState != null) { outState.putBundle(SAVED_DIALOG_STATE_TAG, dialogState); } } outState.putInt(SAVED_STYLE, mStyle); outState.putInt(SAVED_THEME, mTheme); outState.putBoolean(SAVED_CANCELABLE, mCancelable); outState.putInt(SAVED_BACK_STACK_ID, mBackStackId); } @Override public void onStop() { super.onStop(); mDialog.hide(); } /** * Detach from list view. */ @Override public void onDestroyView() { super.onDestroyView(); mDestroyed = true; mDialog.dismiss(); mDialog = null; } }
core/java/android/app/FragmentManager.java +88 −4 Original line number Diff line number Diff line Loading @@ -86,6 +86,10 @@ public class FragmentManager { ArrayList<Integer> mAvailIndices; ArrayList<BackStackEntry> mBackStack; // Must be accessed while locked. ArrayList<BackStackEntry> mBackStackIndices; ArrayList<Integer> mAvailBackStackIndices; int mCurState = Fragment.INITIALIZING; Activity mActivity; Loading Loading @@ -514,6 +518,62 @@ public class FragmentManager { } } public int allocBackStackIndex(BackStackEntry bse) { synchronized (this) { if (mAvailBackStackIndices == null || mAvailBackStackIndices.size() <= 0) { if (mBackStackIndices == null) { mBackStackIndices = new ArrayList<BackStackEntry>(); } int index = mBackStackIndices.size(); if (DEBUG) Log.v(TAG, "Setting back stack index " + index + " to " + bse); mBackStackIndices.add(bse); return index; } else { int index = mAvailBackStackIndices.remove(mAvailBackStackIndices.size()-1); if (DEBUG) Log.v(TAG, "Adding back stack index " + index + " with " + bse); mBackStackIndices.set(index, bse); return index; } } } public void setBackStackIndex(int index, BackStackEntry bse) { synchronized (this) { if (mBackStackIndices == null) { mBackStackIndices = new ArrayList<BackStackEntry>(); } int N = mBackStackIndices.size(); if (index < N) { if (DEBUG) Log.v(TAG, "Setting back stack index " + index + " to " + bse); mBackStackIndices.set(index, bse); } else { while (N < index) { mBackStackIndices.add(null); if (mAvailBackStackIndices == null) { mAvailBackStackIndices = new ArrayList<Integer>(); } if (DEBUG) Log.v(TAG, "Adding available back stack index " + N); mAvailBackStackIndices.add(N); N++; } if (DEBUG) Log.v(TAG, "Adding back stack index " + index + " with " + bse); mBackStackIndices.add(bse); } } } public void freeBackStackIndex(int index) { synchronized (this) { mBackStackIndices.set(index, null); if (mAvailBackStackIndices == null) { mAvailBackStackIndices = new ArrayList<Integer>(); } if (DEBUG) Log.v(TAG, "Freeing back stack index " + index); mAvailBackStackIndices.add(index); } } /** * Only call from main thread! */ Loading Loading @@ -554,11 +614,22 @@ public class FragmentManager { mBackStack.add(state); } public boolean popBackStackState(Handler handler, String name) { public boolean popBackStackState(Handler handler, String name, int flags) { return popBackStackState(handler, name, -1, flags); } public boolean popBackStackState(Handler handler, int id, int flags) { if (id < 0) { return false; } return popBackStackState(handler, null, id, flags); } boolean popBackStackState(Handler handler, String name, int id, int flags) { if (mBackStack == null) { return false; } if (name == null) { if (name == null && id < 0) { int last = mBackStack.size()-1; if (last < 0) { return false; Loading @@ -576,11 +647,21 @@ public class FragmentManager { int index = mBackStack.size()-1; while (index >= 0) { BackStackEntry bss = mBackStack.get(index); if (name.equals(bss.getName())) { if (name != null && name.equals(bss.getName())) { break; } if (id >= 0 && id == bss.mIndex) { break; } index--; } if (index < 0 || index == mBackStack.size()-1) { if (index < 0) { return false; } if ((flags&Activity.POP_BACK_STACK_INCLUSIVE) != 0) { index--; } if (index == mBackStack.size()-1) { return false; } final ArrayList<BackStackEntry> states Loading Loading @@ -772,6 +853,9 @@ public class FragmentManager { for (int i=0; i<fms.mBackStack.length; i++) { BackStackEntry bse = fms.mBackStack[i].instantiate(this); mBackStack.add(bse); if (bse.mIndex >= 0) { setBackStackIndex(bse.mIndex, bse); } } } else { mBackStack = null; Loading