Example usage for android.text Spanned getSpanEnd

List of usage examples for android.text Spanned getSpanEnd

Introduction

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

Prototype

public int getSpanEnd(Object tag);

Source Link

Document

Return the end of the range of text to which the specified markup object is attached, or -1 if the object is not attached.

Usage

From source file:Main.java

/**
 * Apply only the spans from src to dst specific by spans.
 *
 * @see {@link android.text.TextUtils#copySpansFrom}
 *//*w  w  w.  j a  v a  2 s .  c  o m*/
public static void copySpans(@NonNull Spanned src, @NonNull Spannable dst, @NonNull Collection<Object> spans) {
    for (Object span : spans) {
        int start = src.getSpanStart(span);
        int end = src.getSpanEnd(span);
        int flags = src.getSpanFlags(span);
        dst.setSpan(span, start, end, flags);
    }
}

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.
 *//*from   w  ww.j a  v a 2 s. c o m*/
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.googlecode.eyesfree.brailleback.DisplaySpans.java

/**
 * Utility function to log what accessibiility nodes are attached
 * to what parts of the character sequence.
 *///from   www . j  a v a 2  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.facebook.litho.widget.TextSpec.java

@OnPopulateExtraAccessibilityNode
static void onPopulateExtraAccessibilityNode(AccessibilityNodeInfoCompat node, int extraNodeIndex,
        int componentBoundsLeft, int componentBoundsTop, @Prop(resType = STRING) CharSequence text,
        @FromBoundsDefined Layout textLayout, @FromBoundsDefined ClickableSpan[] clickableSpans) {
    final Spanned spanned = (Spanned) text;

    final ClickableSpan span = clickableSpans[extraNodeIndex];
    final int start = spanned.getSpanStart(span);
    final int end = spanned.getSpanEnd(span);
    final int startLine = textLayout.getLineForOffset(start);
    final int endLine = textLayout.getLineForOffset(end);

    // The bounds for multi-line strings should *only* include the first line.  This is because
    // Talkback triggers its click at the center point of these bounds, and if that center point
    // is outside the spannable, it will click on something else.  There is no harm in not outlining
    // the wrapped part of the string, as the text for the whole string will be read regardless of
    // the bounding box.
    final int selectionPathEnd = startLine == endLine ? end : textLayout.getLineVisibleEnd(startLine);

    textLayout.getSelectionPath(start, selectionPathEnd, sTempPath);
    sTempPath.computeBounds(sTempRectF, /* unused */true);

    sTempRect.set(componentBoundsLeft + (int) sTempRectF.left, componentBoundsTop + (int) sTempRectF.top,
            componentBoundsLeft + (int) sTempRectF.right, componentBoundsTop + (int) sTempRectF.bottom);

    if (sTempRect.isEmpty()) {
        // Text is not actually visible.
        // Override bounds so it doesn't crash ExploreByTouchHelper.java
        sTempRect.set(0, 0, 1, 1);/* www .  j  a  va 2 s .  c o  m*/
        node.setBoundsInParent(sTempRect);
        node.setContentDescription(""); // make node non-focusable
        return;
    }

    node.setBoundsInParent(sTempRect);

    node.setClickable(true);
    node.setFocusable(true);
    node.setEnabled(true);
    node.setVisibleToUser(true);
    if (span instanceof AccessibleClickableSpan) {
        node.setText(((AccessibleClickableSpan) span).getAccessibilityDescription());
    } else {
        node.setText(spanned.subSequence(start, end));
    }
}

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

@GetExtraAccessibilityNodeAt
static int getExtraAccessibilityNodeAt(int x, int y, @Prop(resType = STRING) CharSequence text,
        @FromBoundsDefined Layout textLayout, @FromBoundsDefined ClickableSpan[] clickableSpans) {
    final Spanned spanned = (Spanned) text;

    for (int i = 0; i < clickableSpans.length; i++) {
        final ClickableSpan span = clickableSpans[i];
        final int start = spanned.getSpanStart(span);
        final int end = spanned.getSpanEnd(span);

        textLayout.getSelectionPath(start, end, sTempPath);
        sTempPath.computeBounds(sTempRectF, /* unused */true);

        if (sTempRectF.contains(x, y)) {
            return i;
        }/*from  w w  w.  j a v a2s  .  co  m*/
    }

    return INVALID_ID;
}

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
=======/*w w  w  .j  a  va  2  s  .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.jecelyin.editor.v2.core.text.TextUtils.java

private static void writeWhere(Parcel p, Spanned sp, Object o) {
    p.writeInt(sp.getSpanStart(o));//from   w  ww . ja  v a2s . com
    p.writeInt(sp.getSpanEnd(o));
    p.writeInt(sp.getSpanFlags(o));
}

From source file:com.taobao.weex.dom.WXTextDomObject.java

/**
 * Adjust span range after truncate due to the wrong span range during span copy and slicing.
 * @param beforeTruncate The span before truncate
 * @param afterTruncate The span after truncate
 */// ww w . j a  v a  2  s  .  c o m
private void adjustSpansRange(@NonNull Spanned beforeTruncate, @NonNull Spannable afterTruncate) {
    Object[] spans = beforeTruncate.getSpans(0, beforeTruncate.length(), Object.class);
    for (Object span : spans) {
        int start = beforeTruncate.getSpanStart(span);
        int end = beforeTruncate.getSpanEnd(span);
        if (start == 0 && end == beforeTruncate.length()) {
            afterTruncate.removeSpan(span);
            afterTruncate.setSpan(span, 0, afterTruncate.length(), beforeTruncate.getSpanFlags(span));
        }
    }
}

From source file:com.jecelyin.editor.v2.core.text.TextUtils.java

/**
 * Debugging tool to print the spans in a CharSequence.  The output will
 * be printed one span per line.  If the CharSequence is not a Spanned,
 * then the entire string will be printed on a single line.
 */// w  w w .  j  av a  2 s. c o m
public static void dumpSpans(CharSequence cs, Printer printer, String prefix) {
    if (cs instanceof Spanned) {
        Spanned sp = (Spanned) cs;
        Object[] os = sp.getSpans(0, cs.length(), Object.class);

        for (int i = 0; i < os.length; i++) {
            Object o = os[i];
            printer.println(prefix + cs.subSequence(sp.getSpanStart(o), sp.getSpanEnd(o)) + ": "
                    + Integer.toHexString(System.identityHashCode(o)) + " " + o.getClass().getCanonicalName()
                    + " (" + sp.getSpanStart(o) + "-" + sp.getSpanEnd(o) + ") fl=#" + sp.getSpanFlags(o));
        }
    } else {
        printer.println(prefix + cs + ": (no spans)");
    }
}

From source file:com.jecelyin.editor.v2.core.text.TextUtils.java

/**
 * Removes empty spans from the <code>spans</code> array.
 *
 * When parsing a Spanned using {@link android.text.Spanned#nextSpanTransition(int, int, Class)}, empty spans
 * will (correctly) create span transitions, and calling getSpans on a slice of text bounded by
 * one of these transitions will (correctly) include the empty overlapping span.
 *
 * However, these empty spans should not be taken into account when layouting or rendering the
 * string and this method provides a way to filter getSpans' results accordingly.
 *
 * @param spans A list of spans retrieved using {@link android.text.Spanned#getSpans(int, int, Class)} from
 * the <code>spanned</code>/*from   www  .  j ava  2  s . c om*/
 * @param spanned The Spanned from which spans were extracted
 * @return A subset of spans where empty spans ({@link android.text.Spanned#getSpanStart(Object)}  ==
 * {@link android.text.Spanned#getSpanEnd(Object)} have been removed. The initial order is preserved
 * @hide
 */
@SuppressWarnings("unchecked")
public static <T> T[] removeEmptySpans(T[] spans, Spanned spanned, Class<T> klass) {
    T[] copy = null;
    int count = 0;

    for (int i = 0; i < spans.length; i++) {
        final T span = spans[i];
        final int start = spanned.getSpanStart(span);
        final int end = spanned.getSpanEnd(span);

        if (start == end) {
            if (copy == null) {
                copy = (T[]) Array.newInstance(klass, spans.length - 1);
                System.arraycopy(spans, 0, copy, 0, i);
                count = i;
            }
        } else {
            if (copy != null) {
                copy[count] = span;
                count++;
            }
        }
    }

    if (copy != null) {
        T[] result = (T[]) Array.newInstance(klass, count);
        System.arraycopy(copy, 0, result, 0, count);
        return result;
    } else {
        return spans;
    }
}