Loading core/java/android/widget/Editor.java +7 −5 Original line number Diff line number Diff line Loading @@ -3522,7 +3522,8 @@ public class Editor { } } private abstract class HandleView extends View implements TextViewPositionListener { @VisibleForTesting public abstract class HandleView extends View implements TextViewPositionListener { protected Drawable mDrawable; protected Drawable mDrawableLtr; protected Drawable mDrawableRtl; Loading Loading @@ -3553,8 +3554,9 @@ public class Editor { // a different line. protected int mPreviousLineTouched = UNSET_LINE; public HandleView(Drawable drawableLtr, Drawable drawableRtl) { private HandleView(Drawable drawableLtr, Drawable drawableRtl, final int id) { super(mTextView.getContext()); setId(id); mContainer = new PopupWindow(mTextView.getContext(), null, com.android.internal.R.attr.textSelectHandleWindowStyle); mContainer.setSplitTouchEnabled(true); Loading Loading @@ -3916,7 +3918,7 @@ public class Editor { private Runnable mHider; public InsertionHandleView(Drawable drawable) { super(drawable, drawable); super(drawable, drawable, com.android.internal.R.id.insertion_handle); } @Override Loading Loading @@ -4101,7 +4103,7 @@ public class Editor { private final int[] mTextViewLocation = new int[2]; public SelectionStartHandleView(Drawable drawableLtr, Drawable drawableRtl) { super(drawableLtr, drawableRtl); super(drawableLtr, drawableRtl, com.android.internal.R.id.selection_start_handle); ViewConfiguration viewConfiguration = ViewConfiguration.get( mTextView.getContext()); mTextViewEdgeSlop = viewConfiguration.getScaledTouchSlop() * 4; Loading Loading @@ -4341,7 +4343,7 @@ public class Editor { private final int[] mTextViewLocation = new int[2]; public SelectionEndHandleView(Drawable drawableLtr, Drawable drawableRtl) { super(drawableLtr, drawableRtl); super(drawableLtr, drawableRtl, com.android.internal.R.id.selection_end_handle); ViewConfiguration viewConfiguration = ViewConfiguration.get( mTextView.getContext()); mTextViewEdgeSlop = viewConfiguration.getScaledTouchSlop() * 4; Loading core/res/res/values/ids.xml +3 −0 Original line number Diff line number Diff line Loading @@ -97,6 +97,9 @@ <item type="id" name="redo" /> <item type="id" name="replaceText" /> <item type="id" name="shareText" /> <item type="id" name="selection_start_handle" /> <item type="id" name="selection_end_handle" /> <item type="id" name="insertion_handle" /> <item type="id" name="floating_toolbar_menu_item_image_button" /> <!-- Accessibility action identifier for {@link android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_SHOW_ON_SCREEN}. --> Loading core/res/res/values/symbols.xml +3 −0 Original line number Diff line number Diff line Loading @@ -221,6 +221,9 @@ <java-symbol type="id" name="profile_badge_line2" /> <java-symbol type="id" name="profile_badge_line3" /> <java-symbol type="id" name="transitionPosition" /> <java-symbol type="id" name="selection_start_handle" /> <java-symbol type="id" name="selection_end_handle" /> <java-symbol type="id" name="insertion_handle" /> <java-symbol type="attr" name="actionModeShareDrawable" /> <java-symbol type="attr" name="alertDialogCenterButtons" /> Loading core/tests/coretests/src/android/widget/TextViewActivityTest.java +29 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ package android.widget; import static android.widget.espresso.TextViewActions.clickOnTextAtIndex; import static android.widget.espresso.TextViewActions.doubleTapAndDragOnText; import static android.widget.espresso.TextViewActions.doubleClickOnTextAtIndex; import static android.widget.espresso.TextViewActions.dragHandle; import static android.widget.espresso.TextViewActions.Handle; import static android.widget.espresso.TextViewActions.longPressAndDragOnText; import static android.widget.espresso.TextViewActions.longPressOnTextAtIndex; import static android.widget.espresso.TextViewAssertions.hasInsertionPointerAtIndex; Loading @@ -29,11 +31,16 @@ import static android.support.test.espresso.action.ViewActions.click; import static android.support.test.espresso.action.ViewActions.pressKey; import static android.support.test.espresso.action.ViewActions.typeTextIntoFocusedView; import static android.support.test.espresso.assertion.ViewAssertions.matches; import static android.support.test.espresso.matcher.RootMatchers.withDecorView; import static android.support.test.espresso.matcher.ViewMatchers.hasDescendant; import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom; import static android.support.test.espresso.matcher.ViewMatchers.withId; import static android.support.test.espresso.matcher.ViewMatchers.withText; import static org.hamcrest.Matchers.allOf; import com.android.frameworks.coretests.R; import android.support.test.espresso.ViewInteraction; import android.test.ActivityInstrumentationTestCase2; import android.test.suitebuilder.annotation.SmallTest; import android.view.KeyEvent; Loading Loading @@ -157,4 +164,26 @@ public class TextViewActivityTest extends ActivityInstrumentationTestCase2<TextV Thread.sleep(100); assertFloatingToolbarIsDisplayed(getActivity()); } private static ViewInteraction onHandleView(int id) { return onView(allOf(withId(id), isAssignableFrom(Editor.HandleView.class))) .inRoot(withDecorView(hasDescendant(withId(id)))); } @SmallTest public void testSelectionHandles() throws Exception { final String text = "abcd efg hijk lmn"; onView(withId(R.id.textview)).perform(click()); onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text)); onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('f'))); final TextView textView = (TextView)getActivity().findViewById(R.id.textview); onHandleView(com.android.internal.R.id.selection_start_handle) .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('a'))); onView(withId(R.id.textview)).check(hasSelection("abcd efg")); onHandleView(com.android.internal.R.id.selection_end_handle) .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('k') + 1)); onView(withId(R.id.textview)).check(hasSelection("abcd efg hijk")); } } core/tests/coretests/src/android/widget/espresso/DragOnTextViewActions.java→core/tests/coretests/src/android/widget/espresso/DragAction.java +42 −11 Original line number Diff line number Diff line Loading @@ -34,26 +34,25 @@ import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; import android.widget.TextView; import org.hamcrest.Matcher; /** * Drags on text in a TextView using touch events.<br> * Drags on a View using touch events.<br> * <br> * View constraints: * <ul> * <li>must be a TextView displayed on screen * <li>must be displayed on screen * <ul> */ public final class DragOnTextViewActions implements ViewAction { public final class DragAction implements ViewAction { public interface Dragger extends Swiper { UiController wrapUiController(UiController uiController); } /** * Executes different "drag on text" types to given positions. * Executes different drag types to given positions. */ public enum Drag implements Dragger { Loading Loading @@ -82,7 +81,7 @@ public final class DragOnTextViewActions implements ViewAction { @Override public String toString() { return "mouse down and drag to select"; return "mouse down and drag"; } @Override Loading @@ -91,6 +90,35 @@ public final class DragOnTextViewActions implements ViewAction { } }, /** * Starts a drag with a tap. */ TAP { private DownMotionPerformer downMotion = new DownMotionPerformer() { @Override public MotionEvent perform( UiController uiController, float[] coordinates, float[] precision) { MotionEvent downEvent = MotionEvents.sendDown( uiController, coordinates, precision) .down; return downEvent; } }; @Override public Status sendSwipe( UiController uiController, float[] startCoordinates, float[] endCoordinates, float[] precision) { return sendLinearDrag( uiController, downMotion, startCoordinates, endCoordinates, precision); } @Override public String toString() { return "tap and drag"; } }, /** * Starts a drag with a long-press. */ Loading Loading @@ -121,7 +149,7 @@ public final class DragOnTextViewActions implements ViewAction { @Override public String toString() { return "long press and drag to select"; return "long press and drag"; } }, Loading Loading @@ -166,7 +194,7 @@ public final class DragOnTextViewActions implements ViewAction { @Override public String toString() { return "double-tap and drag to select"; return "double-tap and drag"; } }; Loading Loading @@ -258,22 +286,25 @@ public final class DragOnTextViewActions implements ViewAction { private final CoordinatesProvider mStartCoordinatesProvider; private final CoordinatesProvider mEndCoordinatesProvider; private final PrecisionDescriber mPrecisionDescriber; private final Class<? extends View> mViewClass; public DragOnTextViewActions( public DragAction( Dragger dragger, CoordinatesProvider startCoordinatesProvider, CoordinatesProvider endCoordinatesProvider, PrecisionDescriber precisionDescriber) { PrecisionDescriber precisionDescriber, Class<? extends View> viewClass) { mDragger = checkNotNull(dragger); mStartCoordinatesProvider = checkNotNull(startCoordinatesProvider); mEndCoordinatesProvider = checkNotNull(endCoordinatesProvider); mPrecisionDescriber = checkNotNull(precisionDescriber); mViewClass = viewClass; } @Override @SuppressWarnings("unchecked") public Matcher<View> getConstraints() { return allOf(isCompletelyDisplayed(), isAssignableFrom(TextView.class)); return allOf(isCompletelyDisplayed(), isAssignableFrom(mViewClass)); } @Override Loading Loading
core/java/android/widget/Editor.java +7 −5 Original line number Diff line number Diff line Loading @@ -3522,7 +3522,8 @@ public class Editor { } } private abstract class HandleView extends View implements TextViewPositionListener { @VisibleForTesting public abstract class HandleView extends View implements TextViewPositionListener { protected Drawable mDrawable; protected Drawable mDrawableLtr; protected Drawable mDrawableRtl; Loading Loading @@ -3553,8 +3554,9 @@ public class Editor { // a different line. protected int mPreviousLineTouched = UNSET_LINE; public HandleView(Drawable drawableLtr, Drawable drawableRtl) { private HandleView(Drawable drawableLtr, Drawable drawableRtl, final int id) { super(mTextView.getContext()); setId(id); mContainer = new PopupWindow(mTextView.getContext(), null, com.android.internal.R.attr.textSelectHandleWindowStyle); mContainer.setSplitTouchEnabled(true); Loading Loading @@ -3916,7 +3918,7 @@ public class Editor { private Runnable mHider; public InsertionHandleView(Drawable drawable) { super(drawable, drawable); super(drawable, drawable, com.android.internal.R.id.insertion_handle); } @Override Loading Loading @@ -4101,7 +4103,7 @@ public class Editor { private final int[] mTextViewLocation = new int[2]; public SelectionStartHandleView(Drawable drawableLtr, Drawable drawableRtl) { super(drawableLtr, drawableRtl); super(drawableLtr, drawableRtl, com.android.internal.R.id.selection_start_handle); ViewConfiguration viewConfiguration = ViewConfiguration.get( mTextView.getContext()); mTextViewEdgeSlop = viewConfiguration.getScaledTouchSlop() * 4; Loading Loading @@ -4341,7 +4343,7 @@ public class Editor { private final int[] mTextViewLocation = new int[2]; public SelectionEndHandleView(Drawable drawableLtr, Drawable drawableRtl) { super(drawableLtr, drawableRtl); super(drawableLtr, drawableRtl, com.android.internal.R.id.selection_end_handle); ViewConfiguration viewConfiguration = ViewConfiguration.get( mTextView.getContext()); mTextViewEdgeSlop = viewConfiguration.getScaledTouchSlop() * 4; Loading
core/res/res/values/ids.xml +3 −0 Original line number Diff line number Diff line Loading @@ -97,6 +97,9 @@ <item type="id" name="redo" /> <item type="id" name="replaceText" /> <item type="id" name="shareText" /> <item type="id" name="selection_start_handle" /> <item type="id" name="selection_end_handle" /> <item type="id" name="insertion_handle" /> <item type="id" name="floating_toolbar_menu_item_image_button" /> <!-- Accessibility action identifier for {@link android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_SHOW_ON_SCREEN}. --> Loading
core/res/res/values/symbols.xml +3 −0 Original line number Diff line number Diff line Loading @@ -221,6 +221,9 @@ <java-symbol type="id" name="profile_badge_line2" /> <java-symbol type="id" name="profile_badge_line3" /> <java-symbol type="id" name="transitionPosition" /> <java-symbol type="id" name="selection_start_handle" /> <java-symbol type="id" name="selection_end_handle" /> <java-symbol type="id" name="insertion_handle" /> <java-symbol type="attr" name="actionModeShareDrawable" /> <java-symbol type="attr" name="alertDialogCenterButtons" /> Loading
core/tests/coretests/src/android/widget/TextViewActivityTest.java +29 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ package android.widget; import static android.widget.espresso.TextViewActions.clickOnTextAtIndex; import static android.widget.espresso.TextViewActions.doubleTapAndDragOnText; import static android.widget.espresso.TextViewActions.doubleClickOnTextAtIndex; import static android.widget.espresso.TextViewActions.dragHandle; import static android.widget.espresso.TextViewActions.Handle; import static android.widget.espresso.TextViewActions.longPressAndDragOnText; import static android.widget.espresso.TextViewActions.longPressOnTextAtIndex; import static android.widget.espresso.TextViewAssertions.hasInsertionPointerAtIndex; Loading @@ -29,11 +31,16 @@ import static android.support.test.espresso.action.ViewActions.click; import static android.support.test.espresso.action.ViewActions.pressKey; import static android.support.test.espresso.action.ViewActions.typeTextIntoFocusedView; import static android.support.test.espresso.assertion.ViewAssertions.matches; import static android.support.test.espresso.matcher.RootMatchers.withDecorView; import static android.support.test.espresso.matcher.ViewMatchers.hasDescendant; import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom; import static android.support.test.espresso.matcher.ViewMatchers.withId; import static android.support.test.espresso.matcher.ViewMatchers.withText; import static org.hamcrest.Matchers.allOf; import com.android.frameworks.coretests.R; import android.support.test.espresso.ViewInteraction; import android.test.ActivityInstrumentationTestCase2; import android.test.suitebuilder.annotation.SmallTest; import android.view.KeyEvent; Loading Loading @@ -157,4 +164,26 @@ public class TextViewActivityTest extends ActivityInstrumentationTestCase2<TextV Thread.sleep(100); assertFloatingToolbarIsDisplayed(getActivity()); } private static ViewInteraction onHandleView(int id) { return onView(allOf(withId(id), isAssignableFrom(Editor.HandleView.class))) .inRoot(withDecorView(hasDescendant(withId(id)))); } @SmallTest public void testSelectionHandles() throws Exception { final String text = "abcd efg hijk lmn"; onView(withId(R.id.textview)).perform(click()); onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text)); onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('f'))); final TextView textView = (TextView)getActivity().findViewById(R.id.textview); onHandleView(com.android.internal.R.id.selection_start_handle) .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('a'))); onView(withId(R.id.textview)).check(hasSelection("abcd efg")); onHandleView(com.android.internal.R.id.selection_end_handle) .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('k') + 1)); onView(withId(R.id.textview)).check(hasSelection("abcd efg hijk")); } }
core/tests/coretests/src/android/widget/espresso/DragOnTextViewActions.java→core/tests/coretests/src/android/widget/espresso/DragAction.java +42 −11 Original line number Diff line number Diff line Loading @@ -34,26 +34,25 @@ import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; import android.widget.TextView; import org.hamcrest.Matcher; /** * Drags on text in a TextView using touch events.<br> * Drags on a View using touch events.<br> * <br> * View constraints: * <ul> * <li>must be a TextView displayed on screen * <li>must be displayed on screen * <ul> */ public final class DragOnTextViewActions implements ViewAction { public final class DragAction implements ViewAction { public interface Dragger extends Swiper { UiController wrapUiController(UiController uiController); } /** * Executes different "drag on text" types to given positions. * Executes different drag types to given positions. */ public enum Drag implements Dragger { Loading Loading @@ -82,7 +81,7 @@ public final class DragOnTextViewActions implements ViewAction { @Override public String toString() { return "mouse down and drag to select"; return "mouse down and drag"; } @Override Loading @@ -91,6 +90,35 @@ public final class DragOnTextViewActions implements ViewAction { } }, /** * Starts a drag with a tap. */ TAP { private DownMotionPerformer downMotion = new DownMotionPerformer() { @Override public MotionEvent perform( UiController uiController, float[] coordinates, float[] precision) { MotionEvent downEvent = MotionEvents.sendDown( uiController, coordinates, precision) .down; return downEvent; } }; @Override public Status sendSwipe( UiController uiController, float[] startCoordinates, float[] endCoordinates, float[] precision) { return sendLinearDrag( uiController, downMotion, startCoordinates, endCoordinates, precision); } @Override public String toString() { return "tap and drag"; } }, /** * Starts a drag with a long-press. */ Loading Loading @@ -121,7 +149,7 @@ public final class DragOnTextViewActions implements ViewAction { @Override public String toString() { return "long press and drag to select"; return "long press and drag"; } }, Loading Loading @@ -166,7 +194,7 @@ public final class DragOnTextViewActions implements ViewAction { @Override public String toString() { return "double-tap and drag to select"; return "double-tap and drag"; } }; Loading Loading @@ -258,22 +286,25 @@ public final class DragOnTextViewActions implements ViewAction { private final CoordinatesProvider mStartCoordinatesProvider; private final CoordinatesProvider mEndCoordinatesProvider; private final PrecisionDescriber mPrecisionDescriber; private final Class<? extends View> mViewClass; public DragOnTextViewActions( public DragAction( Dragger dragger, CoordinatesProvider startCoordinatesProvider, CoordinatesProvider endCoordinatesProvider, PrecisionDescriber precisionDescriber) { PrecisionDescriber precisionDescriber, Class<? extends View> viewClass) { mDragger = checkNotNull(dragger); mStartCoordinatesProvider = checkNotNull(startCoordinatesProvider); mEndCoordinatesProvider = checkNotNull(endCoordinatesProvider); mPrecisionDescriber = checkNotNull(precisionDescriber); mViewClass = viewClass; } @Override @SuppressWarnings("unchecked") public Matcher<View> getConstraints() { return allOf(isCompletelyDisplayed(), isAssignableFrom(TextView.class)); return allOf(isCompletelyDisplayed(), isAssignableFrom(mViewClass)); } @Override Loading