use of android.text.Spannable in project android_frameworks_base by DirtyUnicorns.
the class TextView method onTouchEvent.
@Override
public boolean onTouchEvent(MotionEvent event) {
final int action = event.getActionMasked();
if (mEditor != null) {
mEditor.onTouchEvent(event);
if (mEditor.mSelectionModifierCursorController != null && mEditor.mSelectionModifierCursorController.isDragAcceleratorActive()) {
return true;
}
}
final boolean superResult = super.onTouchEvent(event);
/*
* Don't handle the release after a long press, because it will move the selection away from
* whatever the menu action was trying to affect. If the long press should have triggered an
* insertion action mode, we can now actually show it.
*/
if (mEditor != null && mEditor.mDiscardNextActionUp && action == MotionEvent.ACTION_UP) {
mEditor.mDiscardNextActionUp = false;
if (mEditor.mIsInsertionActionModeStartPending) {
mEditor.startInsertionActionMode();
mEditor.mIsInsertionActionModeStartPending = false;
}
return superResult;
}
final boolean touchIsFinished = (action == MotionEvent.ACTION_UP) && (mEditor == null || !mEditor.mIgnoreActionUpEvent) && isFocused();
if ((mMovement != null || onCheckIsTextEditor()) && isEnabled() && mText instanceof Spannable && mLayout != null) {
boolean handled = false;
if (mMovement != null) {
handled |= mMovement.onTouchEvent(this, (Spannable) mText, event);
}
final boolean textIsSelectable = isTextSelectable();
if (touchIsFinished && mLinksClickable && mAutoLinkMask != 0 && textIsSelectable) {
// The LinkMovementMethod which should handle taps on links has not been installed
// on non editable text that support text selection.
// We reproduce its behavior here to open links for these.
ClickableSpan[] links = ((Spannable) mText).getSpans(getSelectionStart(), getSelectionEnd(), ClickableSpan.class);
if (links.length > 0) {
links[0].onClick(this);
handled = true;
}
}
if (touchIsFinished && (isTextEditable() || textIsSelectable)) {
// Show the IME, except when selecting in read-only text.
final InputMethodManager imm = InputMethodManager.peekInstance();
viewClicked(imm);
if (!textIsSelectable && mEditor.mShowSoftInputOnFocus) {
handled |= imm != null && imm.showSoftInput(this, 0);
}
// The above condition ensures that the mEditor is not null
mEditor.onTouchUpEvent(event);
handled = true;
}
if (handled) {
return true;
}
}
return superResult;
}
use of android.text.Spannable in project android_frameworks_base by DirtyUnicorns.
the class TextView method onResolvePointerIcon.
@Override
public PointerIcon onResolvePointerIcon(MotionEvent event, int pointerIndex) {
if (mText instanceof Spannable && mLinksClickable) {
final float x = event.getX(pointerIndex);
final float y = event.getY(pointerIndex);
final int offset = getOffsetForPosition(x, y);
final ClickableSpan[] clickables = ((Spannable) mText).getSpans(offset, offset, ClickableSpan.class);
if (clickables.length > 0) {
return PointerIcon.getSystemIcon(mContext, PointerIcon.TYPE_HAND);
}
}
if (isTextSelectable() || isTextEditable()) {
return PointerIcon.getSystemIcon(mContext, PointerIcon.TYPE_TEXT);
}
return super.onResolvePointerIcon(event, pointerIndex);
}
use of android.text.Spannable in project android_frameworks_base by DirtyUnicorns.
the class TextView method onKeyUp.
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (!isEnabled()) {
return super.onKeyUp(keyCode, event);
}
if (!KeyEvent.isModifierKey(keyCode)) {
mPreventDefaultMovement = false;
}
switch(keyCode) {
case KeyEvent.KEYCODE_DPAD_CENTER:
if (event.hasNoModifiers()) {
/*
* If there is a click listener, just call through to
* super, which will invoke it.
*
* If there isn't a click listener, try to show the soft
* input method. (It will also
* call performClick(), but that won't do anything in
* this case.)
*/
if (!hasOnClickListeners()) {
if (mMovement != null && mText instanceof Editable && mLayout != null && onCheckIsTextEditor()) {
InputMethodManager imm = InputMethodManager.peekInstance();
viewClicked(imm);
if (imm != null && getShowSoftInputOnFocus()) {
imm.showSoftInput(this, 0);
}
}
}
}
return super.onKeyUp(keyCode, event);
case KeyEvent.KEYCODE_ENTER:
if (event.hasNoModifiers()) {
if (mEditor != null && mEditor.mInputContentType != null && mEditor.mInputContentType.onEditorActionListener != null && mEditor.mInputContentType.enterDown) {
mEditor.mInputContentType.enterDown = false;
if (mEditor.mInputContentType.onEditorActionListener.onEditorAction(this, EditorInfo.IME_NULL, event)) {
return true;
}
}
if ((event.getFlags() & KeyEvent.FLAG_EDITOR_ACTION) != 0 || shouldAdvanceFocusOnEnter()) {
/*
* If there is a click listener, just call through to
* super, which will invoke it.
*
* If there isn't a click listener, try to advance focus,
* but still call through to super, which will reset the
* pressed state and longpress state. (It will also
* call performClick(), but that won't do anything in
* this case.)
*/
if (!hasOnClickListeners()) {
View v = focusSearch(FOCUS_DOWN);
if (v != null) {
if (!v.requestFocus(FOCUS_DOWN)) {
throw new IllegalStateException("focus search returned a view " + "that wasn't able to take focus!");
}
/*
* Return true because we handled the key; super
* will return false because there was no click
* listener.
*/
super.onKeyUp(keyCode, event);
return true;
} else if ((event.getFlags() & KeyEvent.FLAG_EDITOR_ACTION) != 0) {
// No target for next focus, but make sure the IME
// if this came from it.
InputMethodManager imm = InputMethodManager.peekInstance();
if (imm != null && imm.isActive(this)) {
imm.hideSoftInputFromWindow(getWindowToken(), 0);
}
}
}
}
return super.onKeyUp(keyCode, event);
}
break;
}
if (mEditor != null && mEditor.mKeyListener != null)
if (mEditor.mKeyListener.onKeyUp(this, (Editable) mText, keyCode, event))
return true;
if (mMovement != null && mLayout != null)
if (mMovement.onKeyUp(this, (Spannable) mText, keyCode, event))
return true;
return super.onKeyUp(keyCode, event);
}
use of android.text.Spannable in project android_frameworks_base by DirtyUnicorns.
the class TextView method onKeyMultiple.
@Override
public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
KeyEvent down = KeyEvent.changeAction(event, KeyEvent.ACTION_DOWN);
final int which = doKeyDown(keyCode, down, event);
if (which == KEY_EVENT_NOT_HANDLED) {
// Go through default dispatching.
return super.onKeyMultiple(keyCode, repeatCount, event);
}
if (which == KEY_EVENT_HANDLED) {
// Consumed the whole thing.
return true;
}
repeatCount--;
// We are going to dispatch the remaining events to either the input
// or movement method. To do this, we will just send a repeated stream
// of down and up events until we have done the complete repeatCount.
// It would be nice if those interfaces had an onKeyMultiple() method,
// but adding that is a more complicated change.
KeyEvent up = KeyEvent.changeAction(event, KeyEvent.ACTION_UP);
if (which == KEY_DOWN_HANDLED_BY_KEY_LISTENER) {
// mEditor and mEditor.mInput are not null from doKeyDown
mEditor.mKeyListener.onKeyUp(this, (Editable) mText, keyCode, up);
while (--repeatCount > 0) {
mEditor.mKeyListener.onKeyDown(this, (Editable) mText, keyCode, down);
mEditor.mKeyListener.onKeyUp(this, (Editable) mText, keyCode, up);
}
hideErrorIfUnchanged();
} else if (which == KEY_DOWN_HANDLED_BY_MOVEMENT_METHOD) {
// mMovement is not null from doKeyDown
mMovement.onKeyUp(this, (Spannable) mText, keyCode, up);
while (--repeatCount > 0) {
mMovement.onKeyDown(this, (Spannable) mText, keyCode, down);
mMovement.onKeyUp(this, (Spannable) mText, keyCode, up);
}
}
return true;
}
use of android.text.Spannable in project android_frameworks_base by DirtyUnicorns.
the class TextView method setExtractedText.
/**
* Apply to this text view the given extracted text, as previously
* returned by {@link #extractText(ExtractedTextRequest, ExtractedText)}.
*/
public void setExtractedText(ExtractedText text) {
Editable content = getEditableText();
if (text.text != null) {
if (content == null) {
setText(text.text, TextView.BufferType.EDITABLE);
} else {
int start = 0;
int end = content.length();
if (text.partialStartOffset >= 0) {
final int N = content.length();
start = text.partialStartOffset;
if (start > N)
start = N;
end = text.partialEndOffset;
if (end > N)
end = N;
}
removeParcelableSpans(content, start, end);
if (TextUtils.equals(content.subSequence(start, end), text.text)) {
if (text.text instanceof Spanned) {
// OK to copy spans only.
TextUtils.copySpansFrom((Spanned) text.text, 0, end - start, Object.class, content, start);
}
} else {
content.replace(start, end, text.text);
}
}
}
// Now set the selection position... make sure it is in range, to
// avoid crashes. If this is a partial update, it is possible that
// the underlying text may have changed, causing us problems here.
// Also we just don't want to trust clients to do the right thing.
Spannable sp = (Spannable) getText();
final int N = sp.length();
int start = text.selectionStart;
if (start < 0)
start = 0;
else if (start > N)
start = N;
int end = text.selectionEnd;
if (end < 0)
end = 0;
else if (end > N)
end = N;
Selection.setSelection(sp, start, end);
// Finally, update the selection mode.
if ((text.flags & ExtractedText.FLAG_SELECTING) != 0) {
MetaKeyKeyListener.startSelecting(this, sp);
} else {
MetaKeyKeyListener.stopSelecting(this, sp);
}
}
Aggregations