Example usage for android.text SpannableString subSequence

List of usage examples for android.text SpannableString subSequence

Introduction

In this page you can find the example usage for android.text SpannableString subSequence.

Prototype

public final CharSequence subSequence(int start, int end) 

Source Link

Usage

From source file:com.android.screenspeak.menurules.RuleSpannables.java

@Override
public List<ContextMenuItem> getMenuItemsForNode(ScreenSpeakService service,
        ContextMenuItemBuilder menuItemBuilder, AccessibilityNodeInfoCompat node) {
    final SpannableString spannable = (SpannableString) node.getText();
    final URLSpan[] urlSpans = spannable.getSpans(0, spannable.length(), URLSpan.class);
    final LinkedList<ContextMenuItem> result = new LinkedList<>();

    if ((urlSpans == null) || (urlSpans.length == 0)) {
        return result;
    }//www  . j  av  a2 s .  com

    for (int i = 0; i < urlSpans.length; i++) {
        final URLSpan urlSpan = urlSpans[i];
        final String url = urlSpan.getURL();
        final int start = spannable.getSpanStart(urlSpan);
        final int end = spannable.getSpanEnd(urlSpan);
        final CharSequence label = spannable.subSequence(start, end);
        if (TextUtils.isEmpty(url) || TextUtils.isEmpty(label)) {
            continue;
        }

        final Uri uri = Uri.parse(url);
        if (uri.isRelative()) {
            // Generally, only absolute URIs are resolvable to an activity
            continue;
        }

        final ContextMenuItem item = menuItemBuilder.createMenuItem(service, Menu.NONE, i, Menu.NONE, label);
        item.setOnMenuItemClickListener(new SpannableMenuClickListener(service, uri));
        result.add(item);
    }

    return result;
}

From source file:com.android.talkback.menurules.RuleSpannables.java

@Override
public List<ContextMenuItem> getMenuItemsForNode(TalkBackService service,
        ContextMenuItemBuilder menuItemBuilder, AccessibilityNodeInfoCompat node) {
    final LinkedList<ContextMenuItem> result = new LinkedList<>();

    final SpannableString spannable = getStringWithUrlSpan(node);
    if (spannable == null) {
        return result;
    }/*from   w w w .  j av  a  2s  . com*/

    final URLSpan[] urlSpans = spannable.getSpans(0, spannable.length(), URLSpan.class);
    if ((urlSpans == null) || (urlSpans.length == 0)) {
        return result;
    }

    for (int i = 0; i < urlSpans.length; i++) {
        final URLSpan urlSpan = urlSpans[i];
        final String url = urlSpan.getURL();
        final int start = spannable.getSpanStart(urlSpan);
        final int end = spannable.getSpanEnd(urlSpan);
        final CharSequence label = spannable.subSequence(start, end);
        if (TextUtils.isEmpty(url) || TextUtils.isEmpty(label)) {
            continue;
        }

        final Uri uri = Uri.parse(url);
        if (uri.isRelative()) {
            // Generally, only absolute URIs are resolvable to an activity
            continue;
        }

        final ContextMenuItem item = menuItemBuilder.createMenuItem(service, Menu.NONE, i, Menu.NONE, label);
        item.setOnMenuItemClickListener(new SpannableMenuClickListener(service, uri));
        result.add(item);
    }

    return result;
}

From source file:com.amazon.android.ui.widget.EllipsizedTextView.java

/**
 * Sets ellipsis properties.//from   www. java2  s  .co  m
 *
 * @param widthMeasureSpec  Ellipsis width.
 * @param heightMeasureSpec Ellipsis height.
 * @param layout            Layout for ellipsis.
 * @param lastLine          Last line length for ellipsis.
 * @param maxLines          Max lines in ellipsis.
 */
private void setEllipsis(int widthMeasureSpec, int heightMeasureSpec, Layout layout, int lastLine,
        int maxLines) {

    mIsEllipsized = true;
    setFocusable(true);
    setClickable(true);
    final SpannableString ss = new SpannableString(mCharSequence);
    String visibleText = mCharSequence.toString();

    mEllipsisImage = new StateImageSpan(getContext(), mGuillemetDrawableId, ImageSpan.ALIGN_BASELINE);

    final SpannableStringBuilder spannedText = new SpannableStringBuilder();
    int ellipsisIndex = layout.getLineStart(Math.min(lastLine + 1, maxLines));

    // Keep chopping words off until the ellipsis is on a visible line or there is only one
    // line left.
    do {
        // Only truncate the last line for long description.
        if (lastLine >= maxLines) {
            // Getting the first word break index before the last index of maxline.
            int safeBreakIndex = breakBefore(visibleText, ellipsisIndex, BreakIterator.getWordInstance());
            final int maxLineStart = layout.getLineStart(maxLines - 1);

            // If this check pass, it means we just truncated a word that is longer than a line.
            if (safeBreakIndex < maxLineStart) {
                // Need to check character by character and break in the middle now. Checking
                // word by word should cover most cases, only do this if a word is longer than
                // line width.
                safeBreakIndex = breakBefore(visibleText, ellipsisIndex, BreakIterator.getCharacterInstance());
            }
            ellipsisIndex = safeBreakIndex;
        }

        visibleText = visibleText.substring(0, ellipsisIndex);
        final CharSequence charOutput = ss.subSequence(0, ellipsisIndex);

        // Re-add ellipsis and convert to image
        spannedText.replace(0, spannedText.length(), charOutput);
        spannedText.append(ELLIPSIS);

        spannedText.setSpan(mEllipsisImage, ellipsisIndex, ellipsisIndex + 1, Spanned.SPAN_INCLUSIVE_INCLUSIVE);

        // Reset text and re-measure.
        super.setText(spannedText, BufferType.SPANNABLE);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    } while (getLineCount() > getMaxLines() && getLineCount() > 1);
    requestFocus();
}

From source file:cn.dreamtobe.emoji.ellipsize.helper.SpanEllipsizeEndHelper.java

@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public static CharSequence matchMaxWidth(SpannableString targetText, TextView textView) {
    if (targetText.length() <= 0) {
        return targetText;
    }//from   w  w  w  .jav a2  s.  c o  m

    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
        return targetText;
    }

    if (textView == null) {
        return targetText;
    }

    final int maxWidth = textView.getMaxWidth();

    if (maxWidth <= 0 || maxWidth >= Integer.MAX_VALUE) {
        return targetText;
    }

    if (textView.getEllipsize() != TextUtils.TruncateAt.END) {
        return targetText;
    }

    //TODO Multi-lines support
    if (textView.getMaxLines() != 1) {
        return targetText;
    }

    final String maxWidthKey = getMaxWidthKey(targetText, textView);
    SpannableString tmpText = SPAN_MAXWIDTH_CACHE.get(maxWidthKey);
    if (tmpText != null) {
        removeClickableSpan(tmpText);
        return tmpText;
    }

    TextPaint textPaint = textView.getPaint();
    if (textPaint == null) {
        return targetText;
    }

    final int totalWidth = (int) textPaint.measureText(targetText, 0, targetText.length());
    if (totalWidth <= maxWidth) {
        return targetText;
    }

    final long startTime = System.currentTimeMillis();
    // deal maxwitdh

    final int dotWidth = (int) textPaint.measureText("...");

    tmpText = targetText;

    int start = 0;
    int end = targetText.length();

    // targetX is maxWidth - "...".length
    int targetX = maxWidth - dotWidth;

    //dichotomy: get x most touch targetX
    int middle = targetText.length();
    int x = 0;
    while (start <= end) {
        // tx = targetX, tl = targetLength

        // width:  0           x
        // length: 0         middle           end
        //         -------------|-------------
        middle = (start + end) / 2;

        int emojiDraW = 0;
        int emojiStrW = 0;

        int emojiExcursion = 1;

        final Object[] tmpSpans = tmpText.getSpans(0, middle, Object.class);
        if (tmpSpans != null) {
            for (Object tmpSpan : tmpSpans) {
                final int tmpStart = tmpText.getSpanStart(tmpSpan);
                final int tmpEnd = tmpText.getSpanEnd(tmpSpan);

                //middle in (tmpStart, tmpEnd)
                if (tmpStart < middle && tmpEnd > middle) {
                    middle = tmpEnd;
                    emojiExcursion = tmpEnd - tmpStart;
                }
            }

            // TextPaint#measure do not attention span, so adjust by ourselves
            for (Object tmpSpan : tmpSpans) {
                final int tmpStart = tmpText.getSpanStart(tmpSpan);
                final int tmpEnd = tmpText.getSpanEnd(tmpSpan);

                // TODO support other span
                if (tmpStart < middle && tmpSpan instanceof ImageSpan) {
                    emojiDraW += ((ImageSpan) tmpSpan).getDrawable().getBounds().width();
                    emojiStrW += textPaint.measureText(tmpText, tmpStart, tmpEnd);
                }
            }

        }

        x = (int) textPaint.measureText(tmpText, 0, middle);
        x = x - emojiStrW + emojiDraW;

        //            x = (int) (textPaint.measureText(pureStr, 0, pureStr.length()) + emojiWidth);

        //            Log.d(TAG, String.format("targetX: %d, currentX: %d, currentLength: %d, totalLength: %d, emojiStrW[%d], emojiDraW[%d]", targetX, x, middle, targetText.length(), emojiStrW, emojiDraW));

        if (x > targetX) {
            // width:  0       tx        x
            // length: start   tl      middle         end
            //             ----|---------|-------------
            // TO:     start   |       *end
            //             ----|--------|--------------
            end = middle - emojiExcursion;
        } else if (x < targetX) {
            // width:  0               x       tx
            // length: start         middle    tl     end
            //           --------------|-------|------
            // TO:                      *start  |       end
            //           ---------------|------|------
            start = middle + 1;
        } else {
            break;
        }
    }

    // adjust x larger targetX
    while (x > targetX && middle > 0) {
        x = (int) textPaint.measureText(tmpText, 0, --middle);
    }

    // adjust x middle emoji span
    final Object[] ajustSpans = tmpText.getSpans(0, tmpText.length(), Object.class);
    for (Object adjustSpan : ajustSpans) {
        final int adjustStart = tmpText.getSpanStart(adjustSpan);
        final int adjustEnd = tmpText.getSpanEnd(adjustSpan);

        //[adjustStart, adjustEnd)
        if (middle >= adjustStart && middle < adjustEnd) {
            middle = adjustStart - 1;
            break;
        }
    }

    // finnal middle

    // sub sequence [0, middle + 1) & remove [middle +1, length] spans
    tmpText = (SpannableString) tmpText.subSequence(0, middle + 1);
    //        Log.d(TAG, String.format("sub Sequence[0, %d), [%s] to [%s]", middle + 1, targetText, tmpText));

    // add ...
    final SpannableString maxWidthSS = new SpannableString(tmpText + "...");

    final Object[] maxWidthSpans = tmpText.getSpans(0, tmpText.length(), Object.class);
    if (maxWidthSpans != null) {
        for (Object maxWidthSpan : maxWidthSpans) {
            final int mwSpanStart = tmpText.getSpanStart(maxWidthSpan);
            final int mwSpanEnd = tmpText.getSpanEnd(maxWidthSpan);
            final int mwSpanFlag = tmpText.getSpanFlags(maxWidth);

            maxWidthSS.setSpan(maxWidthSpan, mwSpanStart, mwSpanEnd, mwSpanFlag);
        }
    }

    targetText = maxWidthSS;

    SPAN_MAXWIDTH_CACHE.put(maxWidthKey, targetText);
    Log.d(TAG, String.format("deal maxWidth %d", System.currentTimeMillis() - startTime));

    return targetText;
}