Merge "SmartLinkify - handle keyboard clicks" into pi-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
686fab1464
@@ -25,6 +25,7 @@ import android.text.style.ClickableSpan;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.textclassifier.TextLinks.TextLinkSpan;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
@@ -130,64 +131,70 @@ public class LinkMovementMethod extends ScrollingMovementMethod {
|
||||
selStart = selEnd = -1;
|
||||
|
||||
switch (what) {
|
||||
case CLICK:
|
||||
if (selStart == selEnd) {
|
||||
return false;
|
||||
}
|
||||
case CLICK:
|
||||
if (selStart == selEnd) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ClickableSpan[] link = buffer.getSpans(selStart, selEnd, ClickableSpan.class);
|
||||
ClickableSpan[] links = buffer.getSpans(selStart, selEnd, ClickableSpan.class);
|
||||
|
||||
if (link.length != 1)
|
||||
return false;
|
||||
if (links.length != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
link[0].onClick(widget);
|
||||
break;
|
||||
ClickableSpan link = links[0];
|
||||
if (link instanceof TextLinkSpan) {
|
||||
((TextLinkSpan) link).onClick(widget, TextLinkSpan.INVOCATION_METHOD_KEYBOARD);
|
||||
} else {
|
||||
link.onClick(widget);
|
||||
}
|
||||
break;
|
||||
|
||||
case UP:
|
||||
int bestStart, bestEnd;
|
||||
case UP:
|
||||
int bestStart, bestEnd;
|
||||
|
||||
bestStart = -1;
|
||||
bestEnd = -1;
|
||||
bestStart = -1;
|
||||
bestEnd = -1;
|
||||
|
||||
for (int i = 0; i < candidates.length; i++) {
|
||||
int end = buffer.getSpanEnd(candidates[i]);
|
||||
for (int i = 0; i < candidates.length; i++) {
|
||||
int end = buffer.getSpanEnd(candidates[i]);
|
||||
|
||||
if (end < selEnd || selStart == selEnd) {
|
||||
if (end > bestEnd) {
|
||||
bestStart = buffer.getSpanStart(candidates[i]);
|
||||
bestEnd = end;
|
||||
if (end < selEnd || selStart == selEnd) {
|
||||
if (end > bestEnd) {
|
||||
bestStart = buffer.getSpanStart(candidates[i]);
|
||||
bestEnd = end;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bestStart >= 0) {
|
||||
Selection.setSelection(buffer, bestEnd, bestStart);
|
||||
return true;
|
||||
}
|
||||
if (bestStart >= 0) {
|
||||
Selection.setSelection(buffer, bestEnd, bestStart);
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
break;
|
||||
|
||||
case DOWN:
|
||||
bestStart = Integer.MAX_VALUE;
|
||||
bestEnd = Integer.MAX_VALUE;
|
||||
case DOWN:
|
||||
bestStart = Integer.MAX_VALUE;
|
||||
bestEnd = Integer.MAX_VALUE;
|
||||
|
||||
for (int i = 0; i < candidates.length; i++) {
|
||||
int start = buffer.getSpanStart(candidates[i]);
|
||||
for (int i = 0; i < candidates.length; i++) {
|
||||
int start = buffer.getSpanStart(candidates[i]);
|
||||
|
||||
if (start > selStart || selStart == selEnd) {
|
||||
if (start < bestStart) {
|
||||
bestStart = start;
|
||||
bestEnd = buffer.getSpanEnd(candidates[i]);
|
||||
if (start > selStart || selStart == selEnd) {
|
||||
if (start < bestStart) {
|
||||
bestStart = start;
|
||||
bestEnd = buffer.getSpanEnd(candidates[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bestEnd < Integer.MAX_VALUE) {
|
||||
Selection.setSelection(buffer, bestStart, bestEnd);
|
||||
return true;
|
||||
}
|
||||
if (bestEnd < Integer.MAX_VALUE) {
|
||||
Selection.setSelection(buffer, bestStart, bestEnd);
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -215,8 +222,14 @@ public class LinkMovementMethod extends ScrollingMovementMethod {
|
||||
ClickableSpan[] links = buffer.getSpans(off, off, ClickableSpan.class);
|
||||
|
||||
if (links.length != 0) {
|
||||
ClickableSpan link = links[0];
|
||||
if (action == MotionEvent.ACTION_UP) {
|
||||
links[0].onClick(widget);
|
||||
if (link instanceof TextLinkSpan) {
|
||||
((TextLinkSpan) link).onClick(
|
||||
widget, TextLinkSpan.INVOCATION_METHOD_TOUCH);
|
||||
} else {
|
||||
link.onClick(widget);
|
||||
}
|
||||
} else if (action == MotionEvent.ACTION_DOWN) {
|
||||
if (widget.getContext().getApplicationInfo().targetSdkVersion
|
||||
>= Build.VERSION_CODES.P) {
|
||||
@@ -225,8 +238,8 @@ public class LinkMovementMethod extends ScrollingMovementMethod {
|
||||
widget.hideFloatingToolbar(HIDE_FLOATING_TOOLBAR_DELAY_MS);
|
||||
}
|
||||
Selection.setSelection(buffer,
|
||||
buffer.getSpanStart(links[0]),
|
||||
buffer.getSpanEnd(links[0]));
|
||||
buffer.getSpanStart(link),
|
||||
buffer.getSpanEnd(link));
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
|
||||
@@ -503,6 +503,22 @@ public final class TextLinks implements Parcelable {
|
||||
*/
|
||||
public static class TextLinkSpan extends ClickableSpan {
|
||||
|
||||
/**
|
||||
* How the clickspan is triggered.
|
||||
* @hide
|
||||
*/
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({INVOCATION_METHOD_UNSPECIFIED, INVOCATION_METHOD_TOUCH,
|
||||
INVOCATION_METHOD_KEYBOARD})
|
||||
public @interface InvocationMethod {}
|
||||
|
||||
/** @hide */
|
||||
public static final int INVOCATION_METHOD_UNSPECIFIED = -1;
|
||||
/** @hide */
|
||||
public static final int INVOCATION_METHOD_TOUCH = 0;
|
||||
/** @hide */
|
||||
public static final int INVOCATION_METHOD_KEYBOARD = 1;
|
||||
|
||||
private final TextLink mTextLink;
|
||||
|
||||
public TextLinkSpan(@NonNull TextLink textLink) {
|
||||
@@ -511,16 +527,24 @@ public final class TextLinks implements Parcelable {
|
||||
|
||||
@Override
|
||||
public void onClick(View widget) {
|
||||
onClick(widget, INVOCATION_METHOD_UNSPECIFIED);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public final void onClick(View widget, @InvocationMethod int invocationMethod) {
|
||||
if (widget instanceof TextView) {
|
||||
final TextView textView = (TextView) widget;
|
||||
final Context context = textView.getContext();
|
||||
if (TextClassificationManager.getSettings(context).isSmartLinkifyEnabled()) {
|
||||
if (textView.requestFocus()) {
|
||||
textView.requestActionMode(this);
|
||||
} else {
|
||||
// If textView can not take focus, then simply handle the click as it will
|
||||
// be difficult to get rid of the floating action mode.
|
||||
textView.handleClick(this);
|
||||
switch (invocationMethod) {
|
||||
case INVOCATION_METHOD_TOUCH:
|
||||
textView.requestActionMode(this);
|
||||
break;
|
||||
case INVOCATION_METHOD_KEYBOARD:// fall though
|
||||
case INVOCATION_METHOD_UNSPECIFIED: // fall through
|
||||
default:
|
||||
textView.handleClick(this);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (mTextLink.mUrlSpan != null) {
|
||||
|
||||
Reference in New Issue
Block a user