Example usage for android.text Spanned getSpans

List of usage examples for android.text Spanned getSpans

Introduction

In this page you can find the example usage for android.text Spanned getSpans.

Prototype

public <T> T[] getSpans(int start, int end, Class<T> type);

Source Link

Document

Return an array of the markup objects attached to the specified slice of this CharSequence and whose type is the specified type or a subclass of it.

Usage

From source file:Main.java

public static Object[] getSpans(@NonNull Spanned spanned, int start, int end) {
    Class<Object> anyType = Object.class;
    return spanned.getSpans(start, end, anyType);
}

From source file:com.googlecode.eyesfree.brailleback.DisplaySpans.java

/**
 * Returns a span in {@code spanned} that is {@link Object#equals}
 * to {@code obj}./*from   w  ww. j a  v  a 2 s  .com*/
 */
public static Object getEqualSpan(Spanned spanned, Object obj) {
    Object[] spans = spanned.getSpans(0, spanned.length(), obj.getClass());
    for (Object span : spans) {
        if (obj.equals(span)) {
            return span;
        }
    }
    return null;
}

From source file:Main.java

private static Object getLast(Spanned text, Class kind) {
    /*/*from   w w w .j a  v a  2  s .  c  o  m*/
     * This knows that the last returned object from getSpans()
     * will be the most recently added.
     */
    Object[] objs = text.getSpans(0, text.length(), kind);

    if (objs.length == 0) {
        return null;
    } else {
        return objs[objs.length - 1];
    }
}

From source file:Main.java

/**
 * @see android.text.Html//from www  . ja v a2s.c  om
 */
private static Object getLast(Spanned text, Class<?> kind) {
    /*
     * This knows that the last returned object from getSpans()
     * will be the most recently added.
     */
    Object[] objs = text.getSpans(0, text.length(), kind);
    if (objs.length == 0) {
        return null;
    }
    return objs[objs.length - 1];
}

From source file:com.googlecode.eyesfree.brailleback.DisplaySpans.java

/**
 * Utility function to log what accessibiility nodes are attached
 * to what parts of the character sequence.
 *//*  www.  j a  v a2  s. co  m*/
public static void logNodes(CharSequence chars) {
    if (!(chars instanceof Spanned)) {
        LogUtils.log(DisplaySpans.class, Log.VERBOSE, "Not a Spanned");
        return;
    }
    Spanned spanned = (Spanned) chars;
    AccessibilityNodeInfoCompat spans[] = spanned.getSpans(0, spanned.length(),
            AccessibilityNodeInfoCompat.class);
    for (AccessibilityNodeInfoCompat node : spans) {
        LogUtils.log(DisplaySpans.class, Log.VERBOSE,
                chars.subSequence(spanned.getSpanStart(node), spanned.getSpanEnd(node)).toString());
        LogUtils.log(DisplaySpans.class, Log.VERBOSE, node.getInfo().toString());
    }
}

From source file:com.googlecode.eyesfree.brailleback.DisplaySpans.java

/**
 * Finds the shortest accessibility node span that overlaps {@code position}
 * in {@code chars}.  If a node is found, it is returned, otherwise
 * {@code null} is returned.  If a node is returned, it is still owned
 * by {@code chars} for the purpose of recycling.
 */// ww  w . jav a 2 s  .c om
public static AccessibilityNodeInfoCompat getAccessibilityNodeFromPosition(int position, CharSequence chars) {
    if (!(chars instanceof Spanned)) {
        return null;
    }
    Spanned spanned = (Spanned) chars;
    AccessibilityNodeInfoCompat[] spans = spanned.getSpans(position, position,
            AccessibilityNodeInfoCompat.class);
    if (spans.length == 0) {
        return null;
    }
    AccessibilityNodeInfoCompat found = spans[0];
    int foundLength = spanned.getSpanEnd(found) - spanned.getSpanStart(found);
    for (int i = 1; i < spans.length; ++i) {
        AccessibilityNodeInfoCompat span = spans[i];
        int length = spanned.getSpanEnd(span) - spanned.getSpanStart(span);
        if (length < foundLength) {
            found = span;
            foundLength = length;
        }
    }
    return found;
}

From source file:com.keylesspalace.tusky.util.LinkHelper.java

/**
 * Finds links, mentions, and hashtags in a piece of text and makes them clickable, associating
 * them with callbacks to notify when they're clicked.
 *
 * @param view the returned text will be put in
 * @param content containing text with mentions, links, or hashtags
 * @param mentions any '@' mentions which are known to be in the content
 * @param listener to notify about particular spans that are clicked
 *///w w  w  . j  a  v a2s  .c  o  m
public static void setClickableText(TextView view, Spanned content, @Nullable Status.Mention[] mentions,
        final LinkListener listener) {

    SpannableStringBuilder builder = new SpannableStringBuilder(content);
    URLSpan[] urlSpans = content.getSpans(0, content.length(), URLSpan.class);
    for (URLSpan span : urlSpans) {
        int start = builder.getSpanStart(span);
        int end = builder.getSpanEnd(span);
        int flags = builder.getSpanFlags(span);
        CharSequence text = builder.subSequence(start, end);
        if (text.charAt(0) == '#') {
            final String tag = text.subSequence(1, text.length()).toString();
            ClickableSpan newSpan = new ClickableSpan() {
                @Override
                public void onClick(View widget) {
                    listener.onViewTag(tag);
                }

                @Override
                public void updateDrawState(TextPaint ds) {
                    super.updateDrawState(ds);
                    ds.setUnderlineText(false);
                }
            };
            builder.removeSpan(span);
            builder.setSpan(newSpan, start, end, flags);
        } else if (text.charAt(0) == '@' && mentions != null && mentions.length > 0) {
            String accountUsername = text.subSequence(1, text.length()).toString();
            /* There may be multiple matches for users on different instances with the same
             * username. If a match has the same domain we know it's for sure the same, but if
             * that can't be found then just go with whichever one matched last. */
            String id = null;
            for (Status.Mention mention : mentions) {
                if (mention.localUsername.equalsIgnoreCase(accountUsername)) {
                    id = mention.id;
                    if (mention.url.contains(getDomain(span.getURL()))) {
                        break;
                    }
                }
            }
            if (id != null) {
                final String accountId = id;
                ClickableSpan newSpan = new ClickableSpan() {
                    @Override
                    public void onClick(View widget) {
                        listener.onViewAccount(accountId);
                    }

                    @Override
                    public void updateDrawState(TextPaint ds) {
                        super.updateDrawState(ds);
                        ds.setUnderlineText(false);
                    }
                };
                builder.removeSpan(span);
                builder.setSpan(newSpan, start, end, flags);
            }
        } else {
            ClickableSpan newSpan = new CustomURLSpan(span.getURL());
            builder.removeSpan(span);
            builder.setSpan(newSpan, start, end, flags);
        }
    }
    view.setText(builder);
    view.setLinksClickable(true);
    view.setMovementMethod(LinkMovementMethod.getInstance());
}

From source file:com.zulip.android.util.CustomHtmlToSpannedConverter.java

/**
<<<<<<< e370c9bc00e8f6b33b1d12a44b4c70a7f063c8b9
 * Parses Spanned text for existing html links and reapplies them after the text has been Linkified
=======//from  w ww .j a  va  2s  .co  m
 * Parses Spanned text for existing html links and reapplies them.
>>>>>>> Issue #168 bugfix for links not being clickable, adds autoLink feature including web, phone, map and email
 * @see <a href="https://developer.android.com/reference/android/text/util/Linkify.html">Linkify</a>
 *
 * @param spann
 * @param mask bitmask to define which kinds of links will be searched and applied (e.g. <a href="https://developer.android.com/reference/android/text/util/Linkify.html#ALL">Linkify.ALL</a>)
 * @return
 */
public static Spanned linkifySpanned(@NonNull final Spanned spann, final int mask) {
    URLSpan[] existingSpans = spann.getSpans(0, spann.length(), URLSpan.class);
    List<Pair<Integer, Integer>> links = new ArrayList<>();

    for (URLSpan urlSpan : existingSpans) {
        links.add(new Pair<>(spann.getSpanStart(urlSpan), spann.getSpanEnd(urlSpan)));
    }

    Linkify.addLinks((Spannable) spann, mask);

    // add the links back in
    for (int i = 0; i < existingSpans.length; i++) {
        ((Spannable) spann).setSpan(existingSpans[i], links.get(i).first, links.get(i).second,
                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    }

    return spann;
}

From source file:com.facebook.litho.widget.TextSpec.java

@OnBoundsDefined
static void onBoundsDefined(ComponentContext c, ComponentLayout layout,
        @Prop(resType = ResType.STRING) CharSequence text, @Prop(optional = true) TruncateAt ellipsize,
        @Prop(optional = true, resType = ResType.BOOL) boolean shouldIncludeFontPadding,
        @Prop(optional = true, resType = ResType.INT) int maxLines,
        @Prop(optional = true, resType = ResType.INT) int minEms,
        @Prop(optional = true, resType = ResType.INT) int maxEms,
        @Prop(optional = true, resType = ResType.DIMEN_SIZE) int minWidth,
        @Prop(optional = true, resType = ResType.DIMEN_SIZE) int maxWidth,
        @Prop(optional = true, resType = ResType.DIMEN_OFFSET) float shadowRadius,
        @Prop(optional = true, resType = ResType.DIMEN_OFFSET) float shadowDx,
        @Prop(optional = true, resType = ResType.DIMEN_OFFSET) float shadowDy,
        @Prop(optional = true, resType = ResType.COLOR) int shadowColor,
        @Prop(optional = true, resType = ResType.BOOL) boolean isSingleLine,
        @Prop(optional = true, resType = ResType.COLOR) int textColor,
        @Prop(optional = true) ColorStateList textColorStateList,
        @Prop(optional = true, resType = ResType.COLOR) int linkColor,
        @Prop(optional = true, resType = ResType.DIMEN_TEXT) int textSize,
        @Prop(optional = true, resType = ResType.DIMEN_OFFSET) float extraSpacing,
        @Prop(optional = true, resType = ResType.FLOAT) float spacingMultiplier,
        @Prop(optional = true) VerticalGravity verticalGravity, @Prop(optional = true) int textStyle,
        @Prop(optional = true) Typeface typeface, @Prop(optional = true) Alignment textAlignment,
        @Prop(optional = true) boolean glyphWarming,
        @Prop(optional = true) TextDirectionHeuristicCompat textDirection, @FromMeasure Layout measureLayout,
        @FromMeasure Integer measuredWidth, @FromMeasure Integer measuredHeight, Output<Layout> textLayout,
        Output<Float> textLayoutTranslationY, Output<ClickableSpan[]> clickableSpans,
        Output<ImageSpan[]> imageSpans) {

    if (TextUtils.isEmpty(text)) {
        return;//from w w  w.  jav a  2  s .  com
    }

    final float layoutWidth = layout.getWidth() - layout.getPaddingLeft() - layout.getPaddingRight();
    final float layoutHeight = layout.getHeight() - layout.getPaddingTop() - layout.getPaddingBottom();

    if (measureLayout != null && measuredWidth == layoutWidth && measuredHeight == layoutHeight) {
        textLayout.set(measureLayout);
    } else {
        if (measureLayout != null) {
            Log.w(TAG, "Remeasuring Text component.  This is expensive: consider changing parent layout "
                    + "so that double measurement is not necessary.");
        }

        textLayout.set(createTextLayout(SizeSpec.makeSizeSpec((int) layoutWidth, EXACTLY), ellipsize,
                shouldIncludeFontPadding, maxLines, shadowRadius, shadowDx, shadowDy, shadowColor, isSingleLine,
                text, textColor, textColorStateList, linkColor, textSize, extraSpacing, spacingMultiplier,
                textStyle, typeface, textAlignment, glyphWarming, layout.getResolvedLayoutDirection(), minEms,
                maxEms, minWidth, maxWidth, textDirection));
    }

    final float textHeight = LayoutMeasureUtil.getHeight(textLayout.get());

    switch (verticalGravity) {
    case CENTER:
        textLayoutTranslationY.set((layoutHeight - textHeight) / 2);
        break;

    case BOTTOM:
        textLayoutTranslationY.set(layoutHeight - textHeight);
        break;

    default:
        textLayoutTranslationY.set(0f);
        break;
    }

    if (text instanceof Spanned) {
        Spanned spanned = (Spanned) text;
        clickableSpans.set(spanned.getSpans(0, text.length() - 1, ClickableSpan.class));
        imageSpans.set(spanned.getSpans(0, text.length() - 1, ImageSpan.class));
    }
}

From source file:com.zulip.android.util.CustomHtmlToSpannedConverter.java

private static Object getLast(Spanned text, Class kind) {
    /*/*www .  j ava2s .c om*/
     * This knows that the last returned object from getSpans() will be the
     * most recently added.
     */
    Object[] objs = text.getSpans(0, text.length(), kind);

    if (objs.length == 0) {
        return null;
    } else {
        return objs[objs.length - 1];
    }
}