diff options
author | Xin Li <delphij@google.com> | 2019-07-01 20:59:51 +0000 |
---|---|---|
committer | Xin Li <delphij@google.com> | 2019-07-01 20:59:51 +0000 |
commit | aa06a98b9387bf7cda7948de3f3949e82c151856 (patch) | |
tree | d4d0f1ccfa3d6b82ef0a0be0a353328a3001714d /library/platform/src/com/android/setupwizardlib/view/RichTextView.java | |
parent | f26a9e8e2e422b20c721e199961f11bc82dd250a (diff) | |
parent | 93dacd74efc365bc889773a7cca03adad1ded25d (diff) | |
download | setupwizard-aa06a98b9387bf7cda7948de3f3949e82c151856.tar.gz |
DO NOT MERGE - Merge qt-dev-plus-aosp-without-vendor (5699924) into stage-aosp-mastertemp_140451723
Bug: 134405016
Change-Id: I5e74b54945db4e896b45312ec51d2a4facc01c55
Diffstat (limited to 'library/platform/src/com/android/setupwizardlib/view/RichTextView.java')
-rw-r--r-- | library/platform/src/com/android/setupwizardlib/view/RichTextView.java | 245 |
1 files changed, 122 insertions, 123 deletions
diff --git a/library/platform/src/com/android/setupwizardlib/view/RichTextView.java b/library/platform/src/com/android/setupwizardlib/view/RichTextView.java index fa68a68..7eb29c6 100644 --- a/library/platform/src/com/android/setupwizardlib/view/RichTextView.java +++ b/library/platform/src/com/android/setupwizardlib/view/RichTextView.java @@ -27,15 +27,14 @@ import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.widget.TextView; - import com.android.setupwizardlib.span.LinkSpan; import com.android.setupwizardlib.span.LinkSpan.OnLinkClickListener; import com.android.setupwizardlib.span.SpanHelper; import com.android.setupwizardlib.view.TouchableMovementMethod.TouchableLinkMovementMethod; /** - * An extension of TextView that automatically replaces the annotation tags as specified in - * {@link SpanHelper#replaceSpan(android.text.Spannable, Object, Object)} + * An extension of TextView that automatically replaces the annotation tags as specified in {@link + * SpanHelper#replaceSpan(android.text.Spannable, Object, Object)} * * <p>Note: The accessibility interaction for ClickableSpans (and therefore LinkSpans) are built * into platform in O, although the interaction paradigm is different. (See b/17726921). In this @@ -44,133 +43,133 @@ import com.android.setupwizardlib.view.TouchableMovementMethod.TouchableLinkMove */ public class RichTextView extends TextView implements OnLinkClickListener { - /* static section */ - - private static final String TAG = "RichTextView"; - - private static final String ANNOTATION_LINK = "link"; - private static final String ANNOTATION_TEXT_APPEARANCE = "textAppearance"; - - /** - * Replace <annotation> tags in strings to become their respective types. Currently 2 - * types are supported: - * <ol> - * <li><annotation link="foobar"> will create a - * {@link com.android.setupwizardlib.span.LinkSpan} that broadcasts with the key - * "foobar"</li> - * <li><annotation textAppearance="TextAppearance.FooBar"> will create a - * {@link android.text.style.TextAppearanceSpan} with @style/TextAppearance.FooBar</li> - * </ol> - */ - public static CharSequence getRichText(Context context, CharSequence text) { - if (text instanceof Spanned) { - final SpannableString spannable = new SpannableString(text); - final Annotation[] spans = spannable.getSpans(0, spannable.length(), Annotation.class); - for (Annotation span : spans) { - final String key = span.getKey(); - if (ANNOTATION_TEXT_APPEARANCE.equals(key)) { - String textAppearance = span.getValue(); - final int style = context.getResources() - .getIdentifier(textAppearance, "style", context.getPackageName()); - if (style == 0) { - Log.w(TAG, "Cannot find resource: " + style); - } - final TextAppearanceSpan textAppearanceSpan = - new TextAppearanceSpan(context, style); - SpanHelper.replaceSpan(spannable, span, textAppearanceSpan); - } else if (ANNOTATION_LINK.equals(key)) { - LinkSpan link = new LinkSpan(span.getValue()); - SpanHelper.replaceSpan(spannable, span, link); - } - } - return spannable; + /* static section */ + + private static final String TAG = "RichTextView"; + + private static final String ANNOTATION_LINK = "link"; + private static final String ANNOTATION_TEXT_APPEARANCE = "textAppearance"; + + /** + * Replace <annotation> tags in strings to become their respective types. Currently 2 types + * are supported: + * + * <ol> + * <li><annotation link="foobar"> will create a {@link + * com.android.setupwizardlib.span.LinkSpan} that broadcasts with the key "foobar" + * <li><annotation textAppearance="TextAppearance.FooBar"> will create a {@link + * android.text.style.TextAppearanceSpan} with @style/TextAppearance.FooBar + * </ol> + */ + public static CharSequence getRichText(Context context, CharSequence text) { + if (text instanceof Spanned) { + final SpannableString spannable = new SpannableString(text); + final Annotation[] spans = spannable.getSpans(0, spannable.length(), Annotation.class); + for (Annotation span : spans) { + final String key = span.getKey(); + if (ANNOTATION_TEXT_APPEARANCE.equals(key)) { + String textAppearance = span.getValue(); + final int style = + context + .getResources() + .getIdentifier(textAppearance, "style", context.getPackageName()); + if (style == 0) { + Log.w(TAG, "Cannot find resource: " + style); + } + final TextAppearanceSpan textAppearanceSpan = new TextAppearanceSpan(context, style); + SpanHelper.replaceSpan(spannable, span, textAppearanceSpan); + } else if (ANNOTATION_LINK.equals(key)) { + LinkSpan link = new LinkSpan(span.getValue()); + SpanHelper.replaceSpan(spannable, span, link); } - return text; - } - - /* non-static section */ - - private OnLinkClickListener mOnLinkClickListener; - - public RichTextView(Context context) { - super(context); - } - - public RichTextView(Context context, AttributeSet attrs) { - super(context, attrs); + } + return spannable; } - - @Override - public void setText(CharSequence text, BufferType type) { - text = getRichText(getContext(), text); - // Set text first before doing anything else because setMovementMethod internally calls - // setText. This in turn ends up calling this method with mText as the first parameter - super.setText(text, type); - boolean hasLinks = hasLinks(text); - - if (hasLinks) { - // When a TextView has a movement method, it will set the view to clickable. This makes - // View.onTouchEvent always return true and consumes the touch event, essentially - // nullifying any return values of MovementMethod.onTouchEvent. - // To still allow propagating touch events to the parent when this view doesn't have - // links, we only set the movement method here if the text contains links. - setMovementMethod(TouchableLinkMovementMethod.getInstance()); - } else { - setMovementMethod(null); - } - // ExploreByTouchHelper automatically enables focus for RichTextView - // even though it may not have any links. Causes problems during talkback - // as individual TextViews consume touch events and thereby reducing the focus window - // shown by Talkback. Disable focus if there are no links - setFocusable(hasLinks); - // Do not "reveal" (i.e. scroll to) this view when this view is focused. Since this view is - // focusable in touch mode, we may be focused when the screen is first shown, and starting - // a screen halfway scrolled down is confusing to the user. - setRevealOnFocusHint(false); - setFocusableInTouchMode(hasLinks); + return text; + } + + /* non-static section */ + + private OnLinkClickListener mOnLinkClickListener; + + public RichTextView(Context context) { + super(context); + } + + public RichTextView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + public void setText(CharSequence text, BufferType type) { + text = getRichText(getContext(), text); + // Set text first before doing anything else because setMovementMethod internally calls + // setText. This in turn ends up calling this method with mText as the first parameter + super.setText(text, type); + boolean hasLinks = hasLinks(text); + + if (hasLinks) { + // When a TextView has a movement method, it will set the view to clickable. This makes + // View.onTouchEvent always return true and consumes the touch event, essentially + // nullifying any return values of MovementMethod.onTouchEvent. + // To still allow propagating touch events to the parent when this view doesn't have + // links, we only set the movement method here if the text contains links. + setMovementMethod(TouchableLinkMovementMethod.getInstance()); + } else { + setMovementMethod(null); } - - private boolean hasLinks(CharSequence text) { - if (text instanceof Spanned) { - final ClickableSpan[] spans = - ((Spanned) text).getSpans(0, text.length(), ClickableSpan.class); - return spans.length > 0; - } - return false; + // ExploreByTouchHelper automatically enables focus for RichTextView + // even though it may not have any links. Causes problems during talkback + // as individual TextViews consume touch events and thereby reducing the focus window + // shown by Talkback. Disable focus if there are no links + setFocusable(hasLinks); + // Do not "reveal" (i.e. scroll to) this view when this view is focused. Since this view is + // focusable in touch mode, we may be focused when the screen is first shown, and starting + // a screen halfway scrolled down is confusing to the user. + setRevealOnFocusHint(false); + setFocusableInTouchMode(hasLinks); + } + + private boolean hasLinks(CharSequence text) { + if (text instanceof Spanned) { + final ClickableSpan[] spans = + ((Spanned) text).getSpans(0, text.length(), ClickableSpan.class); + return spans.length > 0; } - - @Override - @SuppressWarnings("ClickableViewAccessibility") // super.onTouchEvent is called - public boolean onTouchEvent(MotionEvent event) { - // Since View#onTouchEvent always return true if the view is clickable (which is the case - // when a TextView has a movement method), override the implementation to allow the movement - // method, if it implements TouchableMovementMethod, to say that the touch is not handled, - // allowing the event to bubble up to the parent view. - boolean superResult = super.onTouchEvent(event); - MovementMethod movementMethod = getMovementMethod(); - if (movementMethod instanceof TouchableMovementMethod) { - TouchableMovementMethod touchableMovementMethod = - (TouchableMovementMethod) movementMethod; - if (touchableMovementMethod.getLastTouchEvent() == event) { - return touchableMovementMethod.isLastTouchEventHandled(); - } - } - return superResult; + return false; + } + + @Override + @SuppressWarnings("ClickableViewAccessibility") // super.onTouchEvent is called + public boolean onTouchEvent(MotionEvent event) { + // Since View#onTouchEvent always return true if the view is clickable (which is the case + // when a TextView has a movement method), override the implementation to allow the movement + // method, if it implements TouchableMovementMethod, to say that the touch is not handled, + // allowing the event to bubble up to the parent view. + boolean superResult = super.onTouchEvent(event); + MovementMethod movementMethod = getMovementMethod(); + if (movementMethod instanceof TouchableMovementMethod) { + TouchableMovementMethod touchableMovementMethod = (TouchableMovementMethod) movementMethod; + if (touchableMovementMethod.getLastTouchEvent() == event) { + return touchableMovementMethod.isLastTouchEventHandled(); + } } + return superResult; + } - public void setOnLinkClickListener(OnLinkClickListener listener) { - mOnLinkClickListener = listener; - } + public void setOnLinkClickListener(OnLinkClickListener listener) { + mOnLinkClickListener = listener; + } - public OnLinkClickListener getOnLinkClickListener() { - return mOnLinkClickListener; - } + public OnLinkClickListener getOnLinkClickListener() { + return mOnLinkClickListener; + } - @Override - public boolean onLinkClick(LinkSpan span) { - if (mOnLinkClickListener != null) { - return mOnLinkClickListener.onLinkClick(span); - } - return false; + @Override + public boolean onLinkClick(LinkSpan span) { + if (mOnLinkClickListener != null) { + return mOnLinkClickListener.onLinkClick(span); } + return false; + } } |