diff options
author | Clara Bayarri <clarabayarri@google.com> | 2015-02-17 15:31:50 +0000 |
---|---|---|
committer | Clara Bayarri <clarabayarri@google.com> | 2015-02-19 22:42:20 +0000 |
commit | 399b51397b98f9e225410adf11b80c8b9c4b1a91 (patch) | |
tree | 7fa86894f17c41da7a2218dadb642c04fc955546 /core | |
parent | ed2a54cfd336bb935f281c04509ecd48c8cf116d (diff) | |
download | frameworks_base-399b51397b98f9e225410adf11b80c8b9c4b1a91.zip frameworks_base-399b51397b98f9e225410adf11b80c8b9c4b1a91.tar.gz frameworks_base-399b51397b98f9e225410adf11b80c8b9c4b1a91.tar.bz2 |
Floating toolbars: Encapsulate StandaloneActionMode view creation.
This CL defines a new interface to be used by ActionModeWrapper.
This allows each client to inject a different primary ActionMode to
the wrapper and keep view creation code next to ActionMode
creation.
The interface method is only called when the wrapper actually
knows that will be the used type, avoinding unnecessary view
creations.
Things pending after this CL:
- Correct handling of ActionModes created by
callback.onWindowStartingActionMode(). This includes all current usages
in an existing ActionBar, as it is handled by Activity. In the current
state, we do not intercept these ActionModes and hence cannot change the
representation.
- Representing the floating type
- Supporting two ActionModes in parallel in DecorView, one of each type
Change-Id: Ic38e209877c3876161d8dd56902e25b51fbe40b6
Diffstat (limited to 'core')
-rw-r--r-- | core/java/android/view/PhoneWindow.java | 147 | ||||
-rw-r--r-- | core/java/com/android/internal/view/ActionModeWrapper.java | 39 |
2 files changed, 103 insertions, 83 deletions
diff --git a/core/java/android/view/PhoneWindow.java b/core/java/android/view/PhoneWindow.java index c8b2ee8..71c922c 100644 --- a/core/java/android/view/PhoneWindow.java +++ b/core/java/android/view/PhoneWindow.java @@ -2694,73 +2694,12 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { if (mActionModeView != null) { mActionModeView.killMode(); } - ActionModeWrapper wrapperMode = - new ActionModeWrapper(mContext, wrappedCallback); + ActionModeWrapper wrapperMode = new ActionModeWrapper( + mContext, wrappedCallback, new StandaloneActionModeProvider()); if (callback.onCreateActionMode(wrapperMode, wrapperMode.getMenu())) { - if (wrapperMode.getType() == ActionMode.TYPE_PRIMARY) { - if (mActionModeView == null) { - if (isFloating()) { - // Use the action bar theme. - final TypedValue outValue = new TypedValue(); - final Theme baseTheme = mContext.getTheme(); - baseTheme.resolveAttribute(R.attr.actionBarTheme, outValue, true); - - final Context actionBarContext; - if (outValue.resourceId != 0) { - final Theme actionBarTheme = mContext.getResources().newTheme(); - actionBarTheme.setTo(baseTheme); - actionBarTheme.applyStyle(outValue.resourceId, true); - - actionBarContext = new ContextThemeWrapper(mContext, 0); - actionBarContext.getTheme().setTo(actionBarTheme); - } else { - actionBarContext = mContext; - } - - mActionModeView = new ActionBarContextView(actionBarContext); - mActionModePopup = new PopupWindow(actionBarContext, null, - R.attr.actionModePopupWindowStyle); - mActionModePopup.setWindowLayoutType( - WindowManager.LayoutParams.TYPE_APPLICATION); - mActionModePopup.setContentView(mActionModeView); - mActionModePopup.setWidth(MATCH_PARENT); - - actionBarContext.getTheme().resolveAttribute( - R.attr.actionBarSize, outValue, true); - final int height = TypedValue.complexToDimensionPixelSize(outValue.data, - actionBarContext.getResources().getDisplayMetrics()); - mActionModeView.setContentHeight(height); - mActionModePopup.setHeight(WRAP_CONTENT); - mShowActionModePopup = new Runnable() { - public void run() { - mActionModePopup.showAtLocation( - mActionModeView.getApplicationWindowToken(), - Gravity.TOP | Gravity.FILL_HORIZONTAL, 0, 0); - } - }; - } else { - ViewStub stub = (ViewStub) findViewById( - R.id.action_mode_bar_stub); - if (stub != null) { - mActionModeView = (ActionBarContextView) stub.inflate(); - } - } - } - if (mActionModeView != null) { - wrapperMode.setActionModeView(mActionModeView); - wrapperMode.setFocusable(mActionModePopup == null); - wrapperMode.lockType(); - wrapperMode.invalidate(); - mActionModeView.initForMode(wrapperMode); - mActionModeView.setVisibility(View.VISIBLE); - mActionMode = wrapperMode; - if (mActionModePopup != null) { - post(mShowActionModePopup); - } - mActionModeView.sendAccessibilityEvent( - AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); - } - } + mActionMode = wrapperMode; + wrapperMode.lockType(); + mActionMode.invalidate(); } else { mActionMode = null; } @@ -3259,6 +3198,82 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { } /** + * Encapsulates the view creation for {@link StandaloneActionMode}. + */ + private class StandaloneActionModeProvider + implements ActionModeWrapper.ActionModeProvider { + + @Override + public ActionMode createActionMode(android.view.ActionMode.Callback callback, + MenuBuilder menuBuilder) { + if (mActionModeView == null) { + if (isFloating()) { + // Use the action bar theme. + final TypedValue outValue = new TypedValue(); + final Theme baseTheme = mContext.getTheme(); + baseTheme.resolveAttribute(R.attr.actionBarTheme, outValue, true); + + final Context actionBarContext; + if (outValue.resourceId != 0) { + final Theme actionBarTheme = mContext.getResources().newTheme(); + actionBarTheme.setTo(baseTheme); + actionBarTheme.applyStyle(outValue.resourceId, true); + + actionBarContext = new ContextThemeWrapper(mContext, 0); + actionBarContext.getTheme().setTo(actionBarTheme); + } else { + actionBarContext = mContext; + } + + mActionModeView = new ActionBarContextView(actionBarContext); + mActionModePopup = new PopupWindow(actionBarContext, null, + R.attr.actionModePopupWindowStyle); + mActionModePopup.setWindowLayoutType( + WindowManager.LayoutParams.TYPE_APPLICATION); + mActionModePopup.setContentView(mActionModeView); + mActionModePopup.setWidth(MATCH_PARENT); + + actionBarContext.getTheme().resolveAttribute( + R.attr.actionBarSize, outValue, true); + final int height = TypedValue.complexToDimensionPixelSize(outValue.data, + actionBarContext.getResources().getDisplayMetrics()); + mActionModeView.setContentHeight(height); + mActionModePopup.setHeight(WRAP_CONTENT); + mShowActionModePopup = new Runnable() { + public void run() { + mActionModePopup.showAtLocation( + mActionModeView.getApplicationWindowToken(), + Gravity.TOP | Gravity.FILL_HORIZONTAL, 0, 0); + } + }; + } else { + ViewStub stub = (ViewStub) findViewById( + R.id.action_mode_bar_stub); + if (stub != null) { + mActionModeView = (ActionBarContextView) stub.inflate(); + } + } + } + if (mActionModeView != null) { + ActionMode mode = new StandaloneActionMode( + mActionModeView.getContext(), mActionModeView, + callback, mActionModePopup == null, menuBuilder); + mActionModeView.killMode(); + mActionModeView.initForMode(mode); + mActionModeView.setVisibility(View.VISIBLE); + if (mActionModePopup != null) { + post(mShowActionModePopup); + } + mActionModeView.sendAccessibilityEvent( + AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); + return mode; + } + return null; + } + + } + + /** * Clears out internal reference when the action mode is destroyed. */ private class ActionModeCallbackWrapper implements ActionMode.Callback { diff --git a/core/java/com/android/internal/view/ActionModeWrapper.java b/core/java/com/android/internal/view/ActionModeWrapper.java index ef1981a..72066b9 100644 --- a/core/java/com/android/internal/view/ActionModeWrapper.java +++ b/core/java/com/android/internal/view/ActionModeWrapper.java @@ -24,7 +24,6 @@ import android.view.MenuItem; import android.view.View; import com.android.internal.view.menu.MenuBuilder; -import com.android.internal.widget.ActionBarContextView; /** * ActionMode implementation that wraps several actions modes and creates them on the fly depending @@ -32,6 +31,22 @@ import com.android.internal.widget.ActionBarContextView; */ public class ActionModeWrapper extends ActionMode { + /** + * Interface to defer the ActionMode creation until the type is chosen. + */ + public interface ActionModeProvider { + /** + * Create the desired ActionMode, that will immediately be used as the current active mode + * in the decorator. + * + * @param callback The {@link ActionMode.Callback} to be used. + * @param menuBuilder The {@link MenuBuilder} that should be used by the created + * {@link ActionMode}. This will already have been populated. + * @return A new {@link ActionMode} ready to be used that uses menuBuilder as its menu. + */ + ActionMode createActionMode(ActionMode.Callback callback, MenuBuilder menuBuilder); + } + private ActionMode mActionMode; private final Context mContext; private MenuBuilder mMenu; @@ -41,16 +56,16 @@ public class ActionModeWrapper extends ActionMode { private CharSequence mTitle; private CharSequence mSubtitle; private View mCustomView; + + private final ActionModeProvider mActionModeProvider; - // Fields for StandaloneActionMode - private ActionBarContextView mActionModeView; - private boolean mIsFocusable; - - public ActionModeWrapper(Context context, ActionMode.Callback callback) { + public ActionModeWrapper( + Context context, ActionMode.Callback callback, ActionModeProvider actionModeProvider) { mContext = context; mMenu = new MenuBuilder(context).setDefaultShowAsAction( MenuItem.SHOW_AS_ACTION_IF_ROOM); mCallback = callback; + mActionModeProvider = actionModeProvider; } @Override @@ -107,9 +122,7 @@ public class ActionModeWrapper extends ActionMode { switch (getType()) { case ActionMode.TYPE_PRIMARY: default: - mActionMode = new StandaloneActionMode( - mActionModeView.getContext(), - mActionModeView, mCallback, mIsFocusable, mMenu); + mActionMode = mActionModeProvider.createActionMode(mCallback, mMenu); break; case ActionMode.TYPE_FLOATING: // Not implemented yet. @@ -189,12 +202,4 @@ public class ActionModeWrapper extends ActionMode { return new MenuInflater(mContext); } - public void setActionModeView(ActionBarContextView actionModeView) { - mActionModeView = actionModeView; - } - - public void setFocusable(boolean focusable) { - mIsFocusable = focusable; - } - } |