Merge "Direct Reply: Fix circular reveal origin" into nyc-mr1-dev

This commit is contained in:
Adrian Roos
2016-07-20 21:49:02 +00:00
committed by Android (Google) Code Review
3 changed files with 64 additions and 14 deletions

View File

@@ -472,20 +472,28 @@ public abstract class BaseStatusBar extends SystemUI implements
} }
} }
riv.setVisibility(View.VISIBLE); int width = view.getWidth();
int cx = view.getLeft() + view.getWidth() / 2; if (view instanceof TextView) {
// Center the reveal on the text which might be off-center from the TextView
TextView tv = (TextView) view;
if (tv.getLayout() != null) {
int innerWidth = (int) tv.getLayout().getLineWidth(0);
innerWidth += tv.getCompoundPaddingLeft() + tv.getCompoundPaddingRight();
width = Math.min(width, innerWidth);
}
}
int cx = view.getLeft() + width / 2;
int cy = view.getTop() + view.getHeight() / 2; int cy = view.getTop() + view.getHeight() / 2;
int w = riv.getWidth(); int w = riv.getWidth();
int h = riv.getHeight(); int h = riv.getHeight();
int r = Math.max( int r = Math.max(
Math.max(cx + cy, cx + (h - cy)), Math.max(cx + cy, cx + (h - cy)),
Math.max((w - cx) + cy, (w - cx) + (h - cy))); Math.max((w - cx) + cy, (w - cx) + (h - cy)));
ViewAnimationUtils.createCircularReveal(riv, cx, cy, 0, r)
.start();
riv.setRevealParameters(cx, cy, r);
riv.setPendingIntent(pendingIntent); riv.setPendingIntent(pendingIntent);
riv.setRemoteInput(inputs, input); riv.setRemoteInput(inputs, input);
riv.focus(); riv.focusAnimated();
return true; return true;
} }

View File

@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.policy; package com.android.systemui.statusbar.policy;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.app.Notification; import android.app.Notification;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.app.RemoteInput; import android.app.RemoteInput;
@@ -33,6 +35,7 @@ import android.view.KeyEvent;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewAnimationUtils;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewParent; import android.view.ViewParent;
import android.view.inputmethod.CompletionInfo; import android.view.inputmethod.CompletionInfo;
@@ -47,11 +50,13 @@ import android.widget.TextView;
import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsProto; import com.android.internal.logging.MetricsProto;
import com.android.systemui.Interpolators;
import com.android.systemui.R; import com.android.systemui.R;
import com.android.systemui.statusbar.ExpandableView; import com.android.systemui.statusbar.ExpandableView;
import com.android.systemui.statusbar.NotificationData; import com.android.systemui.statusbar.NotificationData;
import com.android.systemui.statusbar.RemoteInputController; import com.android.systemui.statusbar.RemoteInputController;
import com.android.systemui.statusbar.stack.ScrollContainer; import com.android.systemui.statusbar.stack.ScrollContainer;
import com.android.systemui.statusbar.stack.StackStateAnimator;
/** /**
* Host for the remote input. * Host for the remote input.
@@ -77,6 +82,10 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
private View mScrollContainerChild; private View mScrollContainerChild;
private boolean mRemoved; private boolean mRemoved;
private int mRevealCx;
private int mRevealCy;
private int mRevealR;
public RemoteInputView(Context context, AttributeSet attrs) { public RemoteInputView(Context context, AttributeSet attrs) {
super(context, attrs); super(context, attrs);
} }
@@ -180,14 +189,28 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
return true; return true;
} }
public void onDefocus() { private void onDefocus(boolean animate) {
mController.removeRemoteInput(mEntry); mController.removeRemoteInput(mEntry);
mEntry.remoteInputText = mEditText.getText(); mEntry.remoteInputText = mEditText.getText();
// During removal, we get reattached and lose focus. Not hiding in that // During removal, we get reattached and lose focus. Not hiding in that
// case to prevent flicker. // case to prevent flicker.
if (!mRemoved) { if (!mRemoved) {
setVisibility(INVISIBLE); if (animate && mRevealR > 0) {
Animator reveal = ViewAnimationUtils.createCircularReveal(
this, mRevealCx, mRevealCy, mRevealR, 0);
reveal.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN);
reveal.setDuration(StackStateAnimator.ANIMATION_DURATION_CLOSE_REMOTE_INPUT);
reveal.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
setVisibility(INVISIBLE);
}
});
reveal.start();
} else {
setVisibility(INVISIBLE);
}
} }
MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_REMOTE_INPUT_CLOSE, MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_REMOTE_INPUT_CLOSE,
mEntry.notification.getPackageName()); mEntry.notification.getPackageName());
@@ -223,6 +246,17 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
mEditText.setHint(mRemoteInput.getLabel()); mEditText.setHint(mRemoteInput.getLabel());
} }
public void focusAnimated() {
if (getVisibility() != VISIBLE) {
Animator animator = ViewAnimationUtils.createCircularReveal(
this, mRevealCx, mRevealCy, 0, mRevealR);
animator.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
animator.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
animator.start();
}
focus();
}
public void focus() { public void focus() {
MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_REMOTE_INPUT_OPEN, MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_REMOTE_INPUT_OPEN,
mEntry.notification.getPackageName()); mEntry.notification.getPackageName());
@@ -253,7 +287,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
mProgressBar.setVisibility(INVISIBLE); mProgressBar.setVisibility(INVISIBLE);
mController.removeSpinning(mEntry.key); mController.removeSpinning(mEntry.key);
updateSendButton(); updateSendButton();
onDefocus(); onDefocus(false /* animate */);
} }
private void updateSendButton() { private void updateSendButton() {
@@ -272,7 +306,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
} }
public void close() { public void close() {
mEditText.defocusIfNeeded(); mEditText.defocusIfNeeded(false /* animated */);
} }
@Override @Override
@@ -321,6 +355,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
other.close(); other.close();
setPendingIntent(other.mPendingIntent); setPendingIntent(other.mPendingIntent);
setRemoteInput(other.mRemoteInputs, other.mRemoteInput); setRemoteInput(other.mRemoteInputs, other.mRemoteInput);
setRevealParameters(other.mRevealCx, other.mRevealCy, other.mRevealR);
focus(); focus();
} }
@@ -374,6 +409,12 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
mRemoved = true; mRemoved = true;
} }
public void setRevealParameters(int cx, int cy, int r) {
mRevealCx = cx;
mRevealCy = cy;
mRevealR = r;
}
/** /**
* An EditText that changes appearance based on whether it's focusable and becomes * An EditText that changes appearance based on whether it's focusable and becomes
* un-focusable whenever the user navigates away from it or it becomes invisible. * un-focusable whenever the user navigates away from it or it becomes invisible.
@@ -389,14 +430,14 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
mBackground = getBackground(); mBackground = getBackground();
} }
private void defocusIfNeeded() { private void defocusIfNeeded(boolean animate) {
if (mRemoteInputView != null && mRemoteInputView.mEntry.row.isChangingPosition()) { if (mRemoteInputView != null && mRemoteInputView.mEntry.row.isChangingPosition()) {
return; return;
} }
if (isFocusable() && isEnabled()) { if (isFocusable() && isEnabled()) {
setInnerFocusable(false); setInnerFocusable(false);
if (mRemoteInputView != null) { if (mRemoteInputView != null) {
mRemoteInputView.onDefocus(); mRemoteInputView.onDefocus(animate);
} }
mShowImeOnInputConnection = false; mShowImeOnInputConnection = false;
} }
@@ -407,7 +448,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
super.onVisibilityChanged(changedView, visibility); super.onVisibilityChanged(changedView, visibility);
if (!isShown()) { if (!isShown()) {
defocusIfNeeded(); defocusIfNeeded(false /* animate */);
} }
} }
@@ -415,7 +456,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) { protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
super.onFocusChanged(focused, direction, previouslyFocusedRect); super.onFocusChanged(focused, direction, previouslyFocusedRect);
if (!focused) { if (!focused) {
defocusIfNeeded(); defocusIfNeeded(true /* animate */);
} }
} }
@@ -434,7 +475,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
@Override @Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) { public boolean onKeyPreIme(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) { if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
defocusIfNeeded(); defocusIfNeeded(true /* animate */);
final InputMethodManager imm = InputMethodManager.getInstance(); final InputMethodManager imm = InputMethodManager.getInstance();
imm.hideSoftInputFromWindow(getWindowToken(), 0); imm.hideSoftInputFromWindow(getWindowToken(), 0);
return true; return true;

View File

@@ -44,6 +44,7 @@ public class StackStateAnimator {
public static final int ANIMATION_DURATION_GO_TO_FULL_SHADE = 448; public static final int ANIMATION_DURATION_GO_TO_FULL_SHADE = 448;
public static final int ANIMATION_DURATION_APPEAR_DISAPPEAR = 464; public static final int ANIMATION_DURATION_APPEAR_DISAPPEAR = 464;
public static final int ANIMATION_DURATION_DIMMED_ACTIVATED = 220; public static final int ANIMATION_DURATION_DIMMED_ACTIVATED = 220;
public static final int ANIMATION_DURATION_CLOSE_REMOTE_INPUT = 150;
public static final int ANIMATION_DURATION_HEADS_UP_APPEAR = 650; public static final int ANIMATION_DURATION_HEADS_UP_APPEAR = 650;
public static final int ANIMATION_DURATION_HEADS_UP_DISAPPEAR = 230; public static final int ANIMATION_DURATION_HEADS_UP_DISAPPEAR = 230;
public static final int ANIMATION_DELAY_PER_ELEMENT_INTERRUPTING = 80; public static final int ANIMATION_DELAY_PER_ELEMENT_INTERRUPTING = 80;