am 03c70cac: am 98f98dd1: Merge "Fix floating toolbar flickers." into mnc-dev

* commit '03c70cac9a0d9dc7c9f2c71b28aaf609393fdcf3':
  Fix floating toolbar flickers.
This commit is contained in:
Abodunrinwa Toki
2015-06-16 21:24:34 +00:00
committed by Android Git Automerger
2 changed files with 57 additions and 50 deletions

View File

@@ -244,15 +244,6 @@ public class Editor {
final CursorAnchorInfoNotifier mCursorAnchorInfoNotifier = new CursorAnchorInfoNotifier(); final CursorAnchorInfoNotifier mCursorAnchorInfoNotifier = new CursorAnchorInfoNotifier();
private final Runnable mHideFloatingToolbar = new Runnable() {
@Override
public void run() {
if (mTextActionMode != null) {
mTextActionMode.hide(ActionMode.DEFAULT_HIDE_DURATION);
}
}
};
private final Runnable mShowFloatingToolbar = new Runnable() { private final Runnable mShowFloatingToolbar = new Runnable() {
@Override @Override
public void run() { public void run() {
@@ -389,7 +380,6 @@ public class Editor {
mTextView.removeCallbacks(mInsertionActionModeRunnable); mTextView.removeCallbacks(mInsertionActionModeRunnable);
} }
mTextView.removeCallbacks(mHideFloatingToolbar);
mTextView.removeCallbacks(mShowFloatingToolbar); mTextView.removeCallbacks(mShowFloatingToolbar);
destroyDisplayListsData(); destroyDisplayListsData();
@@ -1248,14 +1238,12 @@ public class Editor {
private void hideFloatingToolbar() { private void hideFloatingToolbar() {
if (mTextActionMode != null) { if (mTextActionMode != null) {
mTextView.removeCallbacks(mShowFloatingToolbar); mTextView.removeCallbacks(mShowFloatingToolbar);
// Delay the "hide" a little bit just in case a "show" will happen almost immediately. mTextActionMode.hide(ActionMode.DEFAULT_HIDE_DURATION);
mTextView.postDelayed(mHideFloatingToolbar, 100);
} }
} }
private void showFloatingToolbar() { private void showFloatingToolbar() {
if (mTextActionMode != null) { if (mTextActionMode != null) {
mTextView.removeCallbacks(mHideFloatingToolbar);
// Delay "show" so it doesn't interfere with click confirmations // Delay "show" so it doesn't interfere with click confirmations
// or double-clicks that could "dismiss" the floating toolbar. // or double-clicks that could "dismiss" the floating toolbar.
int delay = ViewConfiguration.getDoubleTapTimeout(); int delay = ViewConfiguration.getDoubleTapTimeout();

View File

@@ -48,12 +48,14 @@ public class FloatingActionMode extends ActionMode {
private final Runnable mMovingOff = new Runnable() { private final Runnable mMovingOff = new Runnable() {
public void run() { public void run() {
mFloatingToolbarVisibilityHelper.setMoving(false); mFloatingToolbarVisibilityHelper.setMoving(false);
mFloatingToolbarVisibilityHelper.updateToolbarVisibility();
} }
}; };
private final Runnable mHideOff = new Runnable() { private final Runnable mHideOff = new Runnable() {
public void run() { public void run() {
mFloatingToolbarVisibilityHelper.setHideRequested(false); mFloatingToolbarVisibilityHelper.setHideRequested(false);
mFloatingToolbarVisibilityHelper.updateToolbarVisibility();
} }
}; };
@@ -87,6 +89,7 @@ public class FloatingActionMode extends ActionMode {
} }
}); });
mFloatingToolbarVisibilityHelper = new FloatingToolbarVisibilityHelper(mFloatingToolbar); mFloatingToolbarVisibilityHelper = new FloatingToolbarVisibilityHelper(mFloatingToolbar);
mFloatingToolbarVisibilityHelper.activate();
} }
@Override @Override
@@ -108,8 +111,7 @@ public class FloatingActionMode extends ActionMode {
public void invalidate() { public void invalidate() {
checkToolbarInitialized(); checkToolbarInitialized();
mCallback.onPrepareActionMode(this, mMenu); mCallback.onPrepareActionMode(this, mMenu);
mFloatingToolbar.updateLayout(); invalidateContentRect(); // Will re-layout and show the toolbar if necessary.
invalidateContentRect();
} }
@Override @Override
@@ -131,44 +133,43 @@ public class FloatingActionMode extends ActionMode {
mContentRectOnWindow.set(mContentRect); mContentRectOnWindow.set(mContentRect);
mContentRectOnWindow.offset(mViewPosition[0], mViewPosition[1]); mContentRectOnWindow.offset(mViewPosition[0], mViewPosition[1]);
// Make sure that content rect is not out of the view's visible bounds.
mContentRectOnWindow.set(
Math.max(mContentRectOnWindow.left, mViewRect.left),
Math.max(mContentRectOnWindow.top, mViewRect.top),
Math.min(mContentRectOnWindow.right, mViewRect.right),
Math.min(mContentRectOnWindow.bottom, mViewRect.bottom));
if (!mContentRectOnWindow.equals(mPreviousContentRectOnWindow)) {
if (!mPreviousContentRectOnWindow.isEmpty()) {
notifyContentRectMoving();
}
mFloatingToolbar.setContentRect(mContentRectOnWindow);
mFloatingToolbar.updateLayout();
}
mPreviousContentRectOnWindow.set(mContentRectOnWindow);
if (isContentRectWithinBounds()) { if (isContentRectWithinBounds()) {
mFloatingToolbarVisibilityHelper.setOutOfBounds(false); mFloatingToolbarVisibilityHelper.setOutOfBounds(false);
// Make sure that content rect is not out of the view's visible bounds.
mContentRectOnWindow.set(
Math.max(mContentRectOnWindow.left, mViewRect.left),
Math.max(mContentRectOnWindow.top, mViewRect.top),
Math.min(mContentRectOnWindow.right, mViewRect.right),
Math.min(mContentRectOnWindow.bottom, mViewRect.bottom));
if (!mContentRectOnWindow.equals(mPreviousContentRectOnWindow)) {
// Content rect is moving.
mOriginatingView.removeCallbacks(mMovingOff);
mFloatingToolbarVisibilityHelper.setMoving(true);
mOriginatingView.postDelayed(mMovingOff, MOVING_HIDE_DELAY);
mFloatingToolbar.setContentRect(mContentRectOnWindow);
mFloatingToolbar.updateLayout();
}
} else { } else {
mFloatingToolbarVisibilityHelper.setOutOfBounds(true); mFloatingToolbarVisibilityHelper.setOutOfBounds(true);
mContentRectOnWindow.setEmpty();
} }
mFloatingToolbarVisibilityHelper.updateToolbarVisibility();
mPreviousContentRectOnWindow.set(mContentRectOnWindow);
} }
private boolean isContentRectWithinBounds() { private boolean isContentRectWithinBounds() {
mScreenRect.set( mScreenRect.set(
0, 0,
0, 0,
mContext.getResources().getDisplayMetrics().widthPixels, mContext.getResources().getDisplayMetrics().widthPixels,
mContext.getResources().getDisplayMetrics().heightPixels); mContext.getResources().getDisplayMetrics().heightPixels);
return Rect.intersects(mContentRectOnWindow, mScreenRect) return Rect.intersects(mContentRectOnWindow, mScreenRect)
&& Rect.intersects(mContentRectOnWindow, mViewRect); && Rect.intersects(mContentRectOnWindow, mViewRect);
}
private void notifyContentRectMoving() {
mOriginatingView.removeCallbacks(mMovingOff);
mFloatingToolbarVisibilityHelper.setMoving(true);
mOriginatingView.postDelayed(mMovingOff, MOVING_HIDE_DELAY);
} }
@Override @Override
@@ -184,6 +185,7 @@ public class FloatingActionMode extends ActionMode {
mHideOff.run(); mHideOff.run();
} else { } else {
mFloatingToolbarVisibilityHelper.setHideRequested(true); mFloatingToolbarVisibilityHelper.setHideRequested(true);
mFloatingToolbarVisibilityHelper.updateToolbarVisibility();
mOriginatingView.postDelayed(mHideOff, duration); mOriginatingView.postDelayed(mHideOff, duration);
} }
} }
@@ -221,7 +223,7 @@ public class FloatingActionMode extends ActionMode {
} }
/** /**
* @throws IlllegalStateException * @throws IllegalStateException
*/ */
private void checkToolbarInitialized() { private void checkToolbarInitialized() {
Preconditions.checkState(mFloatingToolbar != null); Preconditions.checkState(mFloatingToolbar != null);
@@ -229,13 +231,14 @@ public class FloatingActionMode extends ActionMode {
} }
private void reset() { private void reset() {
mFloatingToolbarVisibilityHelper.deactivate();
mOriginatingView.removeCallbacks(mMovingOff); mOriginatingView.removeCallbacks(mMovingOff);
mOriginatingView.removeCallbacks(mHideOff); mOriginatingView.removeCallbacks(mHideOff);
} }
/** /**
* A helper that shows/hides the floating toolbar depending on certain states. * A helper for showing/hiding the floating toolbar depending on certain states.
*/ */
private static final class FloatingToolbarVisibilityHelper { private static final class FloatingToolbarVisibilityHelper {
@@ -245,29 +248,45 @@ public class FloatingActionMode extends ActionMode {
private boolean mMoving; private boolean mMoving;
private boolean mOutOfBounds; private boolean mOutOfBounds;
private boolean mActive;
public FloatingToolbarVisibilityHelper(FloatingToolbar toolbar) { public FloatingToolbarVisibilityHelper(FloatingToolbar toolbar) {
mToolbar = Preconditions.checkNotNull(toolbar); mToolbar = Preconditions.checkNotNull(toolbar);
} }
public void activate() {
mHideRequested = false;
mMoving = false;
mOutOfBounds = false;
mActive = true;
}
public void deactivate() {
mActive = false;
mToolbar.dismiss();
}
public void setHideRequested(boolean hide) { public void setHideRequested(boolean hide) {
mHideRequested = hide; mHideRequested = hide;
updateToolbarVisibility();
} }
public void setMoving(boolean moving) { public void setMoving(boolean moving) {
mMoving = moving; mMoving = moving;
updateToolbarVisibility();
} }
public void setOutOfBounds(boolean outOfBounds) { public void setOutOfBounds(boolean outOfBounds) {
mOutOfBounds = outOfBounds; mOutOfBounds = outOfBounds;
updateToolbarVisibility();
} }
private void updateToolbarVisibility() { public void updateToolbarVisibility() {
if (!mActive) {
return;
}
if (mHideRequested || mMoving || mOutOfBounds) { if (mHideRequested || mMoving || mOutOfBounds) {
mToolbar.hide(); mToolbar.hide();
} else if (mToolbar.isHidden()) { } else {
mToolbar.show(); mToolbar.show();
} }
} }