Merge "Hide hint text when starting handwriting" into udc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
3d10089d1e
@@ -21,6 +21,7 @@ import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
@@ -305,6 +306,9 @@ public class HandwritingInitiator {
|
||||
mImm.startStylusHandwriting(view);
|
||||
mState.mHasInitiatedHandwriting = true;
|
||||
mState.mShouldInitHandwriting = false;
|
||||
if (view instanceof TextView) {
|
||||
((TextView) view).hideHint();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -323,6 +327,9 @@ public class HandwritingInitiator {
|
||||
mState.mHasInitiatedHandwriting = true;
|
||||
mState.mShouldInitHandwriting = false;
|
||||
}
|
||||
if (view instanceof TextView) {
|
||||
((TextView) view).hideHint();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -806,6 +806,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
private CharSequence mHint;
|
||||
@UnsupportedAppUsage
|
||||
private Layout mHintLayout;
|
||||
private boolean mHideHint;
|
||||
|
||||
private MovementMethod mMovement;
|
||||
|
||||
@@ -7180,6 +7181,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
sendOnTextChanged(text, 0, oldlen, textLength);
|
||||
onTextChanged(text, 0, oldlen, textLength);
|
||||
|
||||
mHideHint = false;
|
||||
|
||||
if (a11yTextChangeType == AccessibilityUtils.TEXT) {
|
||||
notifyViewAccessibilityStateChangedIfNeeded(
|
||||
AccessibilityEvent.CONTENT_CHANGE_TYPE_TEXT);
|
||||
@@ -7338,6 +7341,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
}
|
||||
|
||||
private void setHintInternal(CharSequence hint) {
|
||||
mHideHint = false;
|
||||
mHint = TextUtils.stringOrSpannedString(hint);
|
||||
|
||||
if (mLayout != null) {
|
||||
@@ -7378,6 +7382,19 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
return mHint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Temporarily hides the hint text until the text is modified, or the hint text is modified, or
|
||||
* the view gains or loses focus.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void hideHint() {
|
||||
if (isShowingHint()) {
|
||||
mHideHint = true;
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the text is constrained to a single horizontally scrolling line ignoring new
|
||||
* line characters instead of letting it wrap onto multiple lines.
|
||||
@@ -8974,7 +8991,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
|
||||
Layout layout = mLayout;
|
||||
|
||||
if (mHint != null && mText.length() == 0) {
|
||||
if (mHint != null && !mHideHint && mText.length() == 0) {
|
||||
if (mHintTextColor != null) {
|
||||
color = mCurHintTextColor;
|
||||
}
|
||||
@@ -11293,7 +11310,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
}
|
||||
|
||||
private boolean isShowingHint() {
|
||||
return TextUtils.isEmpty(mText) && !TextUtils.isEmpty(mHint);
|
||||
return TextUtils.isEmpty(mText) && !TextUtils.isEmpty(mHint) && !mHideHint;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -12437,6 +12454,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
sendOnTextChanged(buffer, start, before, after);
|
||||
onTextChanged(buffer, start, before, after);
|
||||
|
||||
mHideHint = false;
|
||||
clearGesturePreviewHighlight();
|
||||
}
|
||||
|
||||
@@ -12577,6 +12595,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
return;
|
||||
}
|
||||
|
||||
mHideHint = false;
|
||||
|
||||
if (mEditor != null) mEditor.onFocusChanged(focused, direction);
|
||||
|
||||
if (focused) {
|
||||
|
||||
@@ -23,14 +23,20 @@ import static android.view.stylus.HandwritingTestUtil.createView;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyFloat;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.Instrumentation;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Rect;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.view.HandwritingInitiator;
|
||||
@@ -38,7 +44,9 @@ import android.view.InputDevice;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.EditText;
|
||||
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import androidx.test.filters.SmallTest;
|
||||
@@ -47,6 +55,7 @@ import androidx.test.platform.app.InstrumentationRegistry;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
/**
|
||||
* Tests for {@link HandwritingInitiator}
|
||||
@@ -543,6 +552,111 @@ public class HandwritingInitiatorTest {
|
||||
assertThat(mHandwritingInitiator.mConnectedView.get()).isEqualTo(mTestView1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startHandwriting_hidesHint() {
|
||||
EditText editText =
|
||||
new EditText(InstrumentationRegistry.getInstrumentation().getTargetContext());
|
||||
editText.setHint("hint");
|
||||
editText.setLayoutParams(new ViewGroup.LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
|
||||
verifyEditTextDrawsText(editText, "hint");
|
||||
|
||||
mHandwritingInitiator.onTouchEvent(createStylusEvent(ACTION_DOWN, 0, 0, 0));
|
||||
mHandwritingInitiator.startHandwriting(editText);
|
||||
|
||||
verifyEditTextDrawsText(editText, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startHandwriting_clearFocus_restoresHint() {
|
||||
EditText editText =
|
||||
new EditText(InstrumentationRegistry.getInstrumentation().getTargetContext());
|
||||
editText.setHint("hint");
|
||||
editText.setLayoutParams(new ViewGroup.LayoutParams(1024, 1024));
|
||||
editText.requestFocus();
|
||||
|
||||
verifyEditTextDrawsText(editText, "hint");
|
||||
|
||||
mHandwritingInitiator.onTouchEvent(createStylusEvent(ACTION_DOWN, 0, 0, 0));
|
||||
mHandwritingInitiator.startHandwriting(editText);
|
||||
|
||||
verifyEditTextDrawsText(editText, null);
|
||||
|
||||
editText.clearFocus();
|
||||
|
||||
verifyEditTextDrawsText(editText, "hint");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startHandwriting_setHint_restoresHint() {
|
||||
EditText editText =
|
||||
new EditText(InstrumentationRegistry.getInstrumentation().getTargetContext());
|
||||
editText.setHint("hint");
|
||||
editText.setLayoutParams(new ViewGroup.LayoutParams(1024, 1024));
|
||||
|
||||
verifyEditTextDrawsText(editText, "hint");
|
||||
|
||||
mHandwritingInitiator.onTouchEvent(createStylusEvent(ACTION_DOWN, 0, 0, 0));
|
||||
mHandwritingInitiator.startHandwriting(editText);
|
||||
|
||||
verifyEditTextDrawsText(editText, null);
|
||||
|
||||
editText.setHint("new hint");
|
||||
|
||||
verifyEditTextDrawsText(editText, "new hint");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startHandwriting_setText_restoresHint() {
|
||||
EditText editText =
|
||||
new EditText(InstrumentationRegistry.getInstrumentation().getTargetContext());
|
||||
editText.setHint("hint");
|
||||
editText.setLayoutParams(new ViewGroup.LayoutParams(1024, 1024));
|
||||
|
||||
verifyEditTextDrawsText(editText, "hint");
|
||||
|
||||
mHandwritingInitiator.onTouchEvent(createStylusEvent(ACTION_DOWN, 0, 0, 0));
|
||||
mHandwritingInitiator.startHandwriting(editText);
|
||||
|
||||
verifyEditTextDrawsText(editText, null);
|
||||
|
||||
editText.setText("a");
|
||||
editText.setText("");
|
||||
|
||||
verifyEditTextDrawsText(editText, "hint");
|
||||
}
|
||||
|
||||
private void verifyEditTextDrawsText(EditText editText, String text) {
|
||||
editText.measure(
|
||||
View.MeasureSpec.makeMeasureSpec(1024, View.MeasureSpec.AT_MOST),
|
||||
View.MeasureSpec.makeMeasureSpec(1024, View.MeasureSpec.AT_MOST));
|
||||
Canvas canvas = prepareMockCanvas(editText);
|
||||
editText.draw(canvas);
|
||||
if (text != null) {
|
||||
ArgumentCaptor<CharSequence> textCaptor = ArgumentCaptor.forClass(CharSequence.class);
|
||||
verify(canvas).drawText(
|
||||
textCaptor.capture(), anyInt(), anyInt(), anyFloat(), anyFloat(), any());
|
||||
assertThat(textCaptor.getValue().toString()).isEqualTo(text);
|
||||
} else {
|
||||
verify(canvas, never()).drawText(
|
||||
any(CharSequence.class), anyInt(), anyInt(), anyFloat(), anyFloat(), any());
|
||||
}
|
||||
}
|
||||
|
||||
private Canvas prepareMockCanvas(View view) {
|
||||
Canvas canvas = mock(Canvas.class);
|
||||
when(canvas.getClipBounds(any())).thenAnswer(invocation -> {
|
||||
Rect outRect = invocation.getArgument(0);
|
||||
outRect.top = 0;
|
||||
outRect.left = 0;
|
||||
outRect.right = view.getMeasuredWidth();
|
||||
outRect.bottom = view.getMeasuredHeight();
|
||||
return true;
|
||||
});
|
||||
return canvas;
|
||||
}
|
||||
|
||||
private MotionEvent createStylusEvent(int action, int x, int y, long eventTime) {
|
||||
MotionEvent.PointerProperties[] properties = MotionEvent.PointerProperties.createArray(1);
|
||||
properties[0].toolType = MotionEvent.TOOL_TYPE_STYLUS;
|
||||
|
||||
Reference in New Issue
Block a user