am 785c0a02: am 1f21d2a8: Merge "Hide floating toolbar when user interacts with screen." into mnc-dev
* commit '785c0a02c0016fc6c1981bd3e509948d1c1cb227': Hide floating toolbar when user interacts with screen.
This commit is contained in:
@@ -34443,6 +34443,8 @@ package android.view {
|
|||||||
method public abstract void setTitle(int);
|
method public abstract void setTitle(int);
|
||||||
method public void setTitleOptionalHint(boolean);
|
method public void setTitleOptionalHint(boolean);
|
||||||
method public void setType(int);
|
method public void setType(int);
|
||||||
|
method public void snooze(int);
|
||||||
|
field public static final int SNOOZE_TIME_DEFAULT;
|
||||||
field public static final int TYPE_FLOATING = 1; // 0x1
|
field public static final int TYPE_FLOATING = 1; // 0x1
|
||||||
field public static final int TYPE_PRIMARY = 0; // 0x0
|
field public static final int TYPE_PRIMARY = 0; // 0x0
|
||||||
}
|
}
|
||||||
@@ -36507,6 +36509,7 @@ package android.view {
|
|||||||
public class ViewConfiguration {
|
public class ViewConfiguration {
|
||||||
ctor public deprecated ViewConfiguration();
|
ctor public deprecated ViewConfiguration();
|
||||||
method public static android.view.ViewConfiguration get(android.content.Context);
|
method public static android.view.ViewConfiguration get(android.content.Context);
|
||||||
|
method public static int getDefaultActionModeSnoozeTime();
|
||||||
method public static int getDoubleTapTimeout();
|
method public static int getDoubleTapTimeout();
|
||||||
method public static deprecated int getEdgeSlop();
|
method public static deprecated int getEdgeSlop();
|
||||||
method public static deprecated int getFadingEdgeLength();
|
method public static deprecated int getFadingEdgeLength();
|
||||||
|
|||||||
@@ -36706,6 +36706,8 @@ package android.view {
|
|||||||
method public abstract void setTitle(int);
|
method public abstract void setTitle(int);
|
||||||
method public void setTitleOptionalHint(boolean);
|
method public void setTitleOptionalHint(boolean);
|
||||||
method public void setType(int);
|
method public void setType(int);
|
||||||
|
method public void snooze(int);
|
||||||
|
field public static final int SNOOZE_TIME_DEFAULT;
|
||||||
field public static final int TYPE_FLOATING = 1; // 0x1
|
field public static final int TYPE_FLOATING = 1; // 0x1
|
||||||
field public static final int TYPE_PRIMARY = 0; // 0x0
|
field public static final int TYPE_PRIMARY = 0; // 0x0
|
||||||
}
|
}
|
||||||
@@ -38770,6 +38772,7 @@ package android.view {
|
|||||||
public class ViewConfiguration {
|
public class ViewConfiguration {
|
||||||
ctor public deprecated ViewConfiguration();
|
ctor public deprecated ViewConfiguration();
|
||||||
method public static android.view.ViewConfiguration get(android.content.Context);
|
method public static android.view.ViewConfiguration get(android.content.Context);
|
||||||
|
method public static int getDefaultActionModeSnoozeTime();
|
||||||
method public static int getDoubleTapTimeout();
|
method public static int getDoubleTapTimeout();
|
||||||
method public static deprecated int getEdgeSlop();
|
method public static deprecated int getEdgeSlop();
|
||||||
method public static deprecated int getFadingEdgeLength();
|
method public static deprecated int getFadingEdgeLength();
|
||||||
|
|||||||
@@ -44,6 +44,12 @@ public abstract class ActionMode {
|
|||||||
*/
|
*/
|
||||||
public static final int TYPE_FLOATING = 1;
|
public static final int TYPE_FLOATING = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default snooze time.
|
||||||
|
*/
|
||||||
|
public static final int SNOOZE_TIME_DEFAULT =
|
||||||
|
ViewConfiguration.getDefaultActionModeSnoozeTime();
|
||||||
|
|
||||||
private Object mTag;
|
private Object mTag;
|
||||||
private boolean mTitleOptionalHint;
|
private boolean mTitleOptionalHint;
|
||||||
private int mType = TYPE_PRIMARY;
|
private int mType = TYPE_PRIMARY;
|
||||||
@@ -206,6 +212,19 @@ public abstract class ActionMode {
|
|||||||
*/
|
*/
|
||||||
public void invalidateContentRect() {}
|
public void invalidateContentRect() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hide the action mode view from obstructing the content below for a short period.
|
||||||
|
* This only makes sense for action modes that support dynamic positioning on the screen.
|
||||||
|
* If this method is called again before the snooze time expires, the later snooze will
|
||||||
|
* cancel the former and then take effect.
|
||||||
|
* NOTE that there is an internal limit to how long the mode can be snoozed for. It's typically
|
||||||
|
* about a few seconds.
|
||||||
|
*
|
||||||
|
* @param snoozeTime The number of milliseconds to snooze for.
|
||||||
|
* @see #SNOOZE_TIME_DEFAULT
|
||||||
|
*/
|
||||||
|
public void snooze(int snoozeTime) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finish and close this action mode. The action mode's {@link ActionMode.Callback} will
|
* Finish and close this action mode. The action mode's {@link ActionMode.Callback} will
|
||||||
* have its {@link Callback#onDestroyActionMode(ActionMode)} method called.
|
* have its {@link Callback#onDestroyActionMode(ActionMode)} method called.
|
||||||
|
|||||||
@@ -212,6 +212,11 @@ public class ViewConfiguration {
|
|||||||
*/
|
*/
|
||||||
private static final int OVERFLING_DISTANCE = 6;
|
private static final int OVERFLING_DISTANCE = 6;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default time to snooze an action mode for.
|
||||||
|
*/
|
||||||
|
private static final int ACTION_MODE_SNOOZE_TIME_DEFAULT = 2000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration values for overriding {@link #hasPermanentMenuKey()} behavior.
|
* Configuration values for overriding {@link #hasPermanentMenuKey()} behavior.
|
||||||
* These constants must match the definition in res/values/config.xml.
|
* These constants must match the definition in res/values/config.xml.
|
||||||
@@ -731,6 +736,13 @@ public class ViewConfiguration {
|
|||||||
return SCROLL_FRICTION;
|
return SCROLL_FRICTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the default duration in milliseconds for {@link ActionMode#snooze(int)}.
|
||||||
|
*/
|
||||||
|
public static int getDefaultActionModeSnoozeTime() {
|
||||||
|
return ACTION_MODE_SNOOZE_TIME_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Report if the device has a permanent menu key available to the user.
|
* Report if the device has a permanent menu key available to the user.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -233,6 +233,24 @@ public class Editor {
|
|||||||
|
|
||||||
final CursorAnchorInfoNotifier mCursorAnchorInfoNotifier = new CursorAnchorInfoNotifier();
|
final CursorAnchorInfoNotifier mCursorAnchorInfoNotifier = new CursorAnchorInfoNotifier();
|
||||||
|
|
||||||
|
private final Runnable mHideFloatingToolbar = new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (mSelectionActionMode != null) {
|
||||||
|
mSelectionActionMode.snooze(ActionMode.SNOOZE_TIME_DEFAULT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private final Runnable mShowFloatingToolbar = new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (mSelectionActionMode != null) {
|
||||||
|
mSelectionActionMode.snooze(0); // snooze off.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Editor(TextView textView) {
|
Editor(TextView textView) {
|
||||||
mTextView = textView;
|
mTextView = textView;
|
||||||
// Synchronize the filter list, which places the undo input filter at the end.
|
// Synchronize the filter list, which places the undo input filter at the end.
|
||||||
@@ -358,6 +376,9 @@ public class Editor {
|
|||||||
mTextView.removeCallbacks(mSelectionModeWithoutSelectionRunnable);
|
mTextView.removeCallbacks(mSelectionModeWithoutSelectionRunnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mTextView.removeCallbacks(mHideFloatingToolbar);
|
||||||
|
mTextView.removeCallbacks(mShowFloatingToolbar);
|
||||||
|
|
||||||
destroyDisplayListsData();
|
destroyDisplayListsData();
|
||||||
|
|
||||||
if (mSpellChecker != null) {
|
if (mSpellChecker != null) {
|
||||||
@@ -1169,6 +1190,8 @@ public class Editor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void onTouchEvent(MotionEvent event) {
|
void onTouchEvent(MotionEvent event) {
|
||||||
|
updateFloatingToolbarVisibility(event);
|
||||||
|
|
||||||
if (hasSelectionController()) {
|
if (hasSelectionController()) {
|
||||||
getSelectionController().onTouchEvent(event);
|
getSelectionController().onTouchEvent(event);
|
||||||
}
|
}
|
||||||
@@ -1189,6 +1212,37 @@ public class Editor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateFloatingToolbarVisibility(MotionEvent event) {
|
||||||
|
if (mSelectionActionMode != null) {
|
||||||
|
switch (event.getActionMasked()) {
|
||||||
|
case MotionEvent.ACTION_MOVE:
|
||||||
|
hideFloatingToolbar();
|
||||||
|
break;
|
||||||
|
case MotionEvent.ACTION_UP: // fall through
|
||||||
|
case MotionEvent.ACTION_CANCEL:
|
||||||
|
showFloatingToolbar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void hideFloatingToolbar() {
|
||||||
|
if (mSelectionActionMode != null) {
|
||||||
|
mTextView.removeCallbacks(mShowFloatingToolbar);
|
||||||
|
// Delay the "hide" a little bit just in case a "show" will happen almost immediately.
|
||||||
|
mTextView.postDelayed(mHideFloatingToolbar, 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showFloatingToolbar() {
|
||||||
|
if (mSelectionActionMode != null) {
|
||||||
|
mTextView.removeCallbacks(mHideFloatingToolbar);
|
||||||
|
// Delay "show" so it doesn't interfere with click confirmations
|
||||||
|
// or double-clicks that could "dismiss" the floating toolbar.
|
||||||
|
int delay = ViewConfiguration.getDoubleTapTimeout();
|
||||||
|
mTextView.postDelayed(mShowFloatingToolbar, delay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void beginBatchEdit() {
|
public void beginBatchEdit() {
|
||||||
mInBatchEditControllers = true;
|
mInBatchEditControllers = true;
|
||||||
final InputMethodState ims = mInputMethodState;
|
final InputMethodState ims = mInputMethodState;
|
||||||
@@ -3661,6 +3715,8 @@ public class Editor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onTouchEvent(MotionEvent ev) {
|
public boolean onTouchEvent(MotionEvent ev) {
|
||||||
|
updateFloatingToolbarVisibility(ev);
|
||||||
|
|
||||||
switch (ev.getActionMasked()) {
|
switch (ev.getActionMasked()) {
|
||||||
case MotionEvent.ACTION_DOWN: {
|
case MotionEvent.ACTION_DOWN: {
|
||||||
startTouchUpFilter(getCurrentCursorOffset());
|
startTouchUpFilter(getCurrentCursorOffset());
|
||||||
|
|||||||
@@ -30,6 +30,9 @@ import com.android.internal.widget.FloatingToolbar;
|
|||||||
|
|
||||||
public class FloatingActionMode extends ActionMode {
|
public class FloatingActionMode extends ActionMode {
|
||||||
|
|
||||||
|
private static final int MAX_SNOOZE_TIME = 3000;
|
||||||
|
private static final int MOVING_HIDE_DELAY = 300;
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final ActionMode.Callback2 mCallback;
|
private final ActionMode.Callback2 mCallback;
|
||||||
private final MenuBuilder mMenu;
|
private final MenuBuilder mMenu;
|
||||||
@@ -38,12 +41,26 @@ public class FloatingActionMode extends ActionMode {
|
|||||||
private final Rect mPreviousContentRectOnWindow;
|
private final Rect mPreviousContentRectOnWindow;
|
||||||
private final int[] mViewPosition;
|
private final int[] mViewPosition;
|
||||||
private final View mOriginatingView;
|
private final View mOriginatingView;
|
||||||
|
|
||||||
|
private final Runnable mMovingOff = new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
mFloatingToolbarVisibilityHelper.setMoving(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private final Runnable mSnoozeOff = new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
mFloatingToolbarVisibilityHelper.setSnoozed(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private FloatingToolbar mFloatingToolbar;
|
private FloatingToolbar mFloatingToolbar;
|
||||||
|
private FloatingToolbarVisibilityHelper mFloatingToolbarVisibilityHelper;
|
||||||
|
|
||||||
public FloatingActionMode(
|
public FloatingActionMode(
|
||||||
Context context, ActionMode.Callback2 callback, View originatingView) {
|
Context context, ActionMode.Callback2 callback, View originatingView) {
|
||||||
mContext = context;
|
mContext = Preconditions.checkNotNull(context);
|
||||||
mCallback = callback;
|
mCallback = Preconditions.checkNotNull(callback);
|
||||||
mMenu = new MenuBuilder(context).setDefaultShowAsAction(
|
mMenu = new MenuBuilder(context).setDefaultShowAsAction(
|
||||||
MenuItem.SHOW_AS_ACTION_IF_ROOM);
|
MenuItem.SHOW_AS_ACTION_IF_ROOM);
|
||||||
setType(ActionMode.TYPE_FLOATING);
|
setType(ActionMode.TYPE_FLOATING);
|
||||||
@@ -51,7 +68,8 @@ public class FloatingActionMode extends ActionMode {
|
|||||||
mContentRectOnWindow = new Rect();
|
mContentRectOnWindow = new Rect();
|
||||||
mPreviousContentRectOnWindow = new Rect();
|
mPreviousContentRectOnWindow = new Rect();
|
||||||
mViewPosition = new int[2];
|
mViewPosition = new int[2];
|
||||||
mOriginatingView = originatingView;
|
mOriginatingView = Preconditions.checkNotNull(originatingView);
|
||||||
|
mOriginatingView.getLocationInWindow(mViewPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFloatingToolbar(FloatingToolbar floatingToolbar) {
|
public void setFloatingToolbar(FloatingToolbar floatingToolbar) {
|
||||||
@@ -63,6 +81,7 @@ public class FloatingActionMode extends ActionMode {
|
|||||||
return mCallback.onActionItemClicked(FloatingActionMode.this, item);
|
return mCallback.onActionItemClicked(FloatingActionMode.this, item);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
mFloatingToolbarVisibilityHelper = new FloatingToolbarVisibilityHelper(mFloatingToolbar);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -82,7 +101,7 @@ public class FloatingActionMode extends ActionMode {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invalidate() {
|
public void invalidate() {
|
||||||
Preconditions.checkNotNull(mFloatingToolbar);
|
checkToolbarInitialized();
|
||||||
mCallback.onPrepareActionMode(this, mMenu);
|
mCallback.onPrepareActionMode(this, mMenu);
|
||||||
mFloatingToolbar.updateLayout();
|
mFloatingToolbar.updateLayout();
|
||||||
invalidateContentRect();
|
invalidateContentRect();
|
||||||
@@ -90,32 +109,57 @@ public class FloatingActionMode extends ActionMode {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invalidateContentRect() {
|
public void invalidateContentRect() {
|
||||||
Preconditions.checkNotNull(mFloatingToolbar);
|
checkToolbarInitialized();
|
||||||
mCallback.onGetContentRect(this, mOriginatingView, mContentRect);
|
mCallback.onGetContentRect(this, mOriginatingView, mContentRect);
|
||||||
repositionToolbar();
|
repositionToolbar();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateViewLocationInWindow() {
|
public void updateViewLocationInWindow() {
|
||||||
Preconditions.checkNotNull(mFloatingToolbar);
|
checkToolbarInitialized();
|
||||||
mOriginatingView.getLocationInWindow(mViewPosition);
|
mOriginatingView.getLocationInWindow(mViewPosition);
|
||||||
repositionToolbar();
|
repositionToolbar();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void repositionToolbar() {
|
private void repositionToolbar() {
|
||||||
|
checkToolbarInitialized();
|
||||||
mContentRectOnWindow.set(
|
mContentRectOnWindow.set(
|
||||||
mContentRect.left + mViewPosition[0],
|
mContentRect.left + mViewPosition[0],
|
||||||
mContentRect.top + mViewPosition[1],
|
mContentRect.top + mViewPosition[1],
|
||||||
mContentRect.right + mViewPosition[0],
|
mContentRect.right + mViewPosition[0],
|
||||||
mContentRect.bottom + mViewPosition[1]);
|
mContentRect.bottom + mViewPosition[1]);
|
||||||
if (!mContentRectOnWindow.equals(mPreviousContentRectOnWindow)) {
|
if (!mContentRectOnWindow.equals(mPreviousContentRectOnWindow)) {
|
||||||
|
if (!mPreviousContentRectOnWindow.isEmpty()) {
|
||||||
|
notifyContentRectMoving();
|
||||||
|
}
|
||||||
mFloatingToolbar.setContentRect(mContentRectOnWindow);
|
mFloatingToolbar.setContentRect(mContentRectOnWindow);
|
||||||
mFloatingToolbar.updateLayout();
|
mFloatingToolbar.updateLayout();
|
||||||
}
|
}
|
||||||
mPreviousContentRectOnWindow.set(mContentRectOnWindow);
|
mPreviousContentRectOnWindow.set(mContentRectOnWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void notifyContentRectMoving() {
|
||||||
|
mOriginatingView.removeCallbacks(mMovingOff);
|
||||||
|
mFloatingToolbarVisibilityHelper.setMoving(true);
|
||||||
|
mOriginatingView.postDelayed(mMovingOff, MOVING_HIDE_DELAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void snooze(int snoozeTime) {
|
||||||
|
checkToolbarInitialized();
|
||||||
|
snoozeTime = Math.min(MAX_SNOOZE_TIME, snoozeTime);
|
||||||
|
mOriginatingView.removeCallbacks(mSnoozeOff);
|
||||||
|
if (snoozeTime <= 0) {
|
||||||
|
mSnoozeOff.run();
|
||||||
|
} else {
|
||||||
|
mFloatingToolbarVisibilityHelper.setSnoozed(true);
|
||||||
|
mOriginatingView.postDelayed(mSnoozeOff, snoozeTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void finish() {
|
public void finish() {
|
||||||
|
checkToolbarInitialized();
|
||||||
|
reset();
|
||||||
mCallback.onDestroyActionMode(this);
|
mCallback.onDestroyActionMode(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,4 +188,56 @@ public class FloatingActionMode extends ActionMode {
|
|||||||
return new MenuInflater(mContext);
|
return new MenuInflater(mContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws IlllegalStateException
|
||||||
|
*/
|
||||||
|
private void checkToolbarInitialized() {
|
||||||
|
Preconditions.checkState(mFloatingToolbar != null);
|
||||||
|
Preconditions.checkState(mFloatingToolbarVisibilityHelper != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void reset() {
|
||||||
|
mOriginatingView.removeCallbacks(mMovingOff);
|
||||||
|
mOriginatingView.removeCallbacks(mSnoozeOff);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A helper that shows/hides the floating toolbar depending on certain states.
|
||||||
|
*/
|
||||||
|
private static final class FloatingToolbarVisibilityHelper {
|
||||||
|
|
||||||
|
private final FloatingToolbar mToolbar;
|
||||||
|
|
||||||
|
private boolean mSnoozed;
|
||||||
|
private boolean mMoving;
|
||||||
|
private boolean mOutOfBounds;
|
||||||
|
|
||||||
|
public FloatingToolbarVisibilityHelper(FloatingToolbar toolbar) {
|
||||||
|
mToolbar = Preconditions.checkNotNull(toolbar);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSnoozed(boolean snoozed) {
|
||||||
|
mSnoozed = snoozed;
|
||||||
|
updateToolbarVisibility();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMoving(boolean moving) {
|
||||||
|
mMoving = moving;
|
||||||
|
updateToolbarVisibility();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOutOfBounds(boolean outOfBounds) {
|
||||||
|
mOutOfBounds = outOfBounds;
|
||||||
|
updateToolbarVisibility();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateToolbarVisibility() {
|
||||||
|
if (mSnoozed || mMoving || mOutOfBounds) {
|
||||||
|
mToolbar.hide();
|
||||||
|
} else if (mToolbar.isHidden()) {
|
||||||
|
mToolbar.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user