Java Code Examples for android.text.Spannable#getSpanEnd()

The following examples show how to use android.text.Spannable#getSpanEnd() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: TextChipsEditView.java    From talk-android with MIT License 6 votes vote down vote up
/**
 * Remove the chip and any text associated with it from the RecipientEditTextView.
 */
// Visible for testing.
/* package */
public void removeChip(DrawableRecipientChip chip) {
    Spannable spannable = getSpannable();
    int spanStart = spannable.getSpanStart(chip);
    int spanEnd = spannable.getSpanEnd(chip);
    Editable text = getText();
    int toDelete = spanEnd;
    boolean wasSelected = chip == mSelectedChip;
    // Clear that there is a selected chip before updating any text.
    if (wasSelected) {
        mSelectedChip = null;
    }
    // Always remove trailing spaces when removing a chip.
    while (toDelete >= 0 && toDelete < text.length() && text.charAt(toDelete) == ' ') {
        toDelete++;
    }
    spannable.removeSpan(chip);
    if (spanStart >= 0 && toDelete > 0) {
        text.delete(spanStart, toDelete);
    }
    if (wasSelected) {
        clearSelectedChip();
    }
}
 
Example 2
Source File: LinkTransformationMethod.java    From EdXposedManager with GNU General Public License v3.0 6 votes vote down vote up
@Override
public CharSequence getTransformation(CharSequence source, View view) {
    if (view instanceof TextView) {
        TextView textView = (TextView) view;
        Linkify.addLinks(textView, Linkify.WEB_URLS);
        if (textView.getText() == null || !(textView.getText() instanceof Spannable)) {
            return source;
        }
        Spannable text = (Spannable) textView.getText();
        URLSpan[] spans = text.getSpans(0, textView.length(), URLSpan.class);
        for (int i = spans.length - 1; i >= 0; i--) {
            URLSpan oldSpan = spans[i];
            int start = text.getSpanStart(oldSpan);
            int end = text.getSpanEnd(oldSpan);
            String url = oldSpan.getURL();
            text.removeSpan(oldSpan);
            text.setSpan(new CustomTabsURLSpan(activity, url), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
        return text;
    }
    return source;
}
 
Example 3
Source File: MultiSelectEditText.java    From AutoCompleteBubbleText with Apache License 2.0 5 votes vote down vote up
@Override
public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
    if(text instanceof Spannable){
        Spannable spanned = ((Spannable)text);
        ImageSpan[] includingSpans = spanned.getSpans(0, end, ImageSpan.class);
        if(includingSpans.length != 0){
            ImageSpan lastSpan = includingSpans[includingSpans.length-1];
            int endPoint = spanned.getSpanEnd(lastSpan);
            if(end == endPoint)
                super.draw(canvas, text, start, end, x, top, y, bottom, paint);
        }
    }
    else
        super.draw(canvas, text, start, end, x, top, y, bottom, paint);
}
 
Example 4
Source File: LinksHelper.java    From X-Alarm with GNU Affero General Public License v3.0 5 votes vote down vote up
/**
 * Remove underline
 * @param textView
 */
public static void stripUnderlines(TextView textView) {
    Spannable s = (Spannable) textView.getText();
    URLSpan[] spans = s.getSpans(0, s.length(), URLSpan.class);

    for (URLSpan span: spans) {
        int start = s.getSpanStart(span);
        int end = s.getSpanEnd(span);
        s.removeSpan(span);
        span = new URLSpanNoUnderline(span.getURL());
        s.setSpan(span, start, end, 0);
    }

    textView.setText(s);
}
 
Example 5
Source File: StickerManager.java    From Zom-Android-XMPP with GNU General Public License v3.0 5 votes vote down vote up
public boolean addEmoji(Context context, Spannable spannable) throws IOException {
	boolean hasChanges = false;
	for (Entry<Pattern, Sticker> entry : emoticons.entrySet())
	{
		Matcher matcher = entry.getKey().matcher(spannable);
		while (matcher.find()) {
			boolean set = true;
			for (ImageSpan span : spannable.getSpans(matcher.start(),
			        matcher.end(), ImageSpan.class))
				
			    if (spannable.getSpanStart(span) >= matcher.start()
			            && spannable.getSpanEnd(span) <= matcher.end())
			        spannable.removeSpan(span);
			    else {
			        set = false;
			        break;
			    }
			if (set) {
			    hasChanges = true;
			    
			    Sticker emoji = entry.getValue();
			    spannable.setSpan(new ImageSpan(context, BitmapFactory.decodeStream(emoji.res.getAssets().open(emoji.assetUri.getPath()))),
			            matcher.start(), matcher.end(),
			            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
			}
		}
	}
	return hasChanges;
}
 
Example 6
Source File: QuestionWidget.java    From commcare-android with Apache License 2.0 5 votes vote down vote up
private void stripUnderlines(TextView textView) {
    Spannable s = (Spannable)textView.getText();
    URLSpan[] spans = s.getSpans(0, s.length(), URLSpan.class);
    for (URLSpan span : spans) {
        int start = s.getSpanStart(span);
        int end = s.getSpanEnd(span);
        s.removeSpan(span);
        span = new URLSpanNoUnderline(span.getURL());
        s.setSpan(span, start, end, 0);
    }
    textView.setText(s);
}
 
Example 7
Source File: TextChipsEditView.java    From talk-android with MIT License 5 votes vote down vote up
/**
 * Replace the more chip, if it exists, with all of the recipient chips it had
 * replaced when the RecipientEditTextView gains focus.
 */
public void removeMoreChip() {
    if (mMoreChip != null) {
        Spannable span = getSpannable();
        span.removeSpan(mMoreChip);
        mMoreChip = null;
        // Re-add the spans that were removed.
        if (mRemovedSpans != null && mRemovedSpans.size() > 0) {
            // Recreate each removed span.
            DrawableRecipientChip[] recipients = getSortedRecipients();
            // Start the search for tokens after the last currently visible
            // chip.
            if (recipients == null || recipients.length == 0) {
                return;
            }
            int end = span.getSpanEnd(recipients[recipients.length - 1]);
            Editable editable = getText();
            for (DrawableRecipientChip chip : mRemovedSpans) {
                int chipStart;
                int chipEnd;
                String token;
                // Need to find the location of the chip, again.
                token = (String) chip.getOriginalText();
                // As we find the matching recipient for the remove spans,
                // reduce the size of the string we need to search.
                // That way, if there are duplicates, we always find the correct
                // recipient.
                chipStart = editable.toString().indexOf(token, end);
                end = chipEnd = Math.min(editable.length(), chipStart + token.length());
                // Only set the span if we found a matching token.
                if (chipStart != -1) {
                    editable.setSpan(chip, chipStart, chipEnd,
                            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                }
            }
            mRemovedSpans.clear();
        }
    }
}
 
Example 8
Source File: RecipientEditTextView.java    From talk-android with MIT License 5 votes vote down vote up
/**
 * Replace the more chip, if it exists, with all of the recipient chips it had
 * replaced when the RecipientEditTextView gains focus.
 */
public void removeMoreChip() {
    if (mMoreChip != null) {
        Spannable span = getSpannable();
        span.removeSpan(mMoreChip);
        mMoreChip = null;
        // Re-add the spans that were removed.
        if (mRemovedSpans != null && mRemovedSpans.size() > 0) {
            // Recreate each removed span.
            DrawableRecipientChip[] recipients = getSortedRecipients();
            // Start the search for tokens after the last currently visible
            // chip.
            if (recipients == null || recipients.length == 0) {
                return;
            }
            int end = span.getSpanEnd(recipients[recipients.length - 1]);
            Editable editable = getText();
            for (DrawableRecipientChip chip : mRemovedSpans) {
                int chipStart;
                int chipEnd;
                String token;
                // Need to find the location of the chip, again.
                token = (String) chip.getOriginalText();
                // As we find the matching recipient for the remove spans,
                // reduce the size of the string we need to search.
                // That way, if there are duplicates, we always find the correct
                // recipient.
                chipStart = editable.toString().indexOf(token, end);
                end = chipEnd = Math.min(editable.length(), chipStart + token.length());
                // Only set the span if we found a matching token.
                if (chipStart != -1) {
                    editable.setSpan(chip, chipStart, chipEnd,
                            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                }
            }
            mRemovedSpans.clear();
        }
    }
}
 
Example 9
Source File: MessageFormatter.java    From talk-android with MIT License 5 votes vote down vote up
public static Spannable formatURLSpan(String str) {
    Spannable s = new SpannableStringBuilder(str);
    Linkify.addLinks(s, Linkify.WEB_URLS);
    URLSpan[] urlSpans = s.getSpans(0, s.length(), URLSpan.class);
    for (URLSpan urlSpan : urlSpans) {
        int start = s.getSpanStart(urlSpan);
        int end = s.getSpanEnd(urlSpan);
        s.removeSpan(urlSpan);
        s.setSpan(new TalkURLSpan(urlSpan.getURL(), ThemeUtil.getThemeColor(MainApp.CONTEXT.
                        getResources(), BizLogic.getTeamColor())), start, end,
                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    }
    return s;
}
 
Example 10
Source File: RichLinkViewTelegram.java    From RichLinkPreview with Apache License 2.0 5 votes vote down vote up
private static void removeUnderlines(Spannable p_Text) {
    URLSpan[] spans = p_Text.getSpans(0, p_Text.length(), URLSpan.class);

    for(URLSpan span:spans) {
        int start = p_Text.getSpanStart(span);
        int end = p_Text.getSpanEnd(span);
        p_Text.removeSpan(span);
        span = new URLSpanNoUnderline(span.getURL());
        p_Text.setSpan(span, start, end, 0);
    }
}
 
Example 11
Source File: EaseSmileUtils.java    From Study_Android_Demo with Apache License 2.0 5 votes vote down vote up
/**
 * replace existing spannable with smiles
 * @param context
 * @param spannable
 * @return
 */
public static boolean addSmiles(Context context, Spannable spannable) {
    boolean hasChanges = false;
    for (Entry<Pattern, Object> entry : emoticons.entrySet()) {
        Matcher matcher = entry.getKey().matcher(spannable);
        while (matcher.find()) {
            boolean set = true;
            for (ImageSpan span : spannable.getSpans(matcher.start(),
                    matcher.end(), ImageSpan.class))
                if (spannable.getSpanStart(span) >= matcher.start()
                        && spannable.getSpanEnd(span) <= matcher.end())
                    spannable.removeSpan(span);
                else {
                    set = false;
                    break;
                }
            if (set) {
                hasChanges = true;
                Object value = entry.getValue();
                if(value instanceof String && !((String) value).startsWith("http")){
                    File file = new File((String) value);
                    if(!file.exists() || file.isDirectory()){
                        return false;
                    }
                    spannable.setSpan(new ImageSpan(context, Uri.fromFile(file)),
                            matcher.start(), matcher.end(),
                            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                }else{
                    spannable.setSpan(new ImageSpan(context, (Integer)value),
                            matcher.start(), matcher.end(),
                            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                }
            }
        }
    }
    
    return hasChanges;
}
 
Example 12
Source File: AlertsCreator.java    From Telegram with GNU General Public License v2.0 5 votes vote down vote up
public static AlertDialog createSupportAlert(BaseFragment fragment) {
    if (fragment == null || fragment.getParentActivity() == null) {
        return null;
    }
    final TextView message = new TextView(fragment.getParentActivity());
    Spannable spanned = new SpannableString(Html.fromHtml(LocaleController.getString("AskAQuestionInfo", R.string.AskAQuestionInfo).replace("\n", "<br>")));
    URLSpan[] spans = spanned.getSpans(0, spanned.length(), URLSpan.class);
    for (int i = 0; i < spans.length; i++) {
        URLSpan span = spans[i];
        int start = spanned.getSpanStart(span);
        int end = spanned.getSpanEnd(span);
        spanned.removeSpan(span);
        span = new URLSpanNoUnderline(span.getURL()) {
            @Override
            public void onClick(View widget) {
                fragment.dismissCurrentDialig();
                super.onClick(widget);
            }
        };
        spanned.setSpan(span, start, end, 0);
    }
    message.setText(spanned);
    message.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
    message.setLinkTextColor(Theme.getColor(Theme.key_dialogTextLink));
    message.setHighlightColor(Theme.getColor(Theme.key_dialogLinkSelection));
    message.setPadding(AndroidUtilities.dp(23), 0, AndroidUtilities.dp(23), 0);
    message.setMovementMethod(new AndroidUtilities.LinkMovementMethodMy());
    message.setTextColor(Theme.getColor(Theme.key_dialogTextBlack));

    AlertDialog.Builder builder1 = new AlertDialog.Builder(fragment.getParentActivity());
    builder1.setView(message);
    builder1.setTitle(LocaleController.getString("AskAQuestion", R.string.AskAQuestion));
    builder1.setPositiveButton(LocaleController.getString("AskButton", R.string.AskButton), (dialogInterface, i) -> performAskAQuestion(fragment));
    builder1.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
    return builder1.create();
}
 
Example 13
Source File: RichTextView.java    From YiBo with Apache License 2.0 5 votes vote down vote up
private void stripUnderlines(Spannable s) {
    URLSpan[] spans = s.getSpans(0, s.length(), URLSpan.class);
    for (URLSpan span: spans) {
        int start = s.getSpanStart(span);
        int end = s.getSpanEnd(span);
        s.removeSpan(span);
        span = new URLSpanNoUnderline(span.getURL());
        s.setSpan(span, start, end, 0);
    }
}
 
Example 14
Source File: RichEditor.java    From RichEditor with MIT License 4 votes vote down vote up
private <T> void terminateStyle(Spannable spannable, T s) {
    int start = spannable.getSpanStart(s);
    int end = spannable.getSpanEnd(s);
    spannable.removeSpan(s);
    spannable.setSpan(s, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
 
Example 15
Source File: LongClickableLinkMovementMethod.java    From iBeebo with GNU General Public License v3.0 4 votes vote down vote up
private boolean action(int what, TextView widget, Spannable buffer) {
    Layout layout = widget.getLayout();

    int padding = widget.getTotalPaddingTop() + widget.getTotalPaddingBottom();
    int areatop = widget.getScrollY();
    int areabot = areatop + widget.getHeight() - padding;

    int linetop = layout.getLineForVertical(areatop);
    int linebot = layout.getLineForVertical(areabot);

    int first = layout.getLineStart(linetop);
    int last = layout.getLineEnd(linebot);

    MyURLSpan[] candidates = buffer.getSpans(first, last, MyURLSpan.class);

    int a = Selection.getSelectionStart(buffer);
    int b = Selection.getSelectionEnd(buffer);

    int selStart = Math.min(a, b);
    int selEnd = Math.max(a, b);

    if (selStart < 0) {
        if (buffer.getSpanStart(FROM_BELOW) >= 0) {
            selStart = selEnd = buffer.length();
        }
    }

    if (selStart > last) {
        selStart = selEnd = Integer.MAX_VALUE;
    }
    if (selEnd < first) {
        selStart = selEnd = -1;
    }

    switch (what) {
        case CLICK:
            if (selStart == selEnd) {
                return false;
            }

            MyURLSpan[] link = buffer.getSpans(selStart, selEnd, MyURLSpan.class);

            if (link.length != 1) {
                return false;
            }

            link[0].onClick(widget);
            break;

        case UP:
            int best_start = -1;
            int best_end = -1;

            for (MyURLSpan candidate1 : candidates) {
                int end = buffer.getSpanEnd(candidate1);

                if (end < selEnd || selStart == selEnd) {
                    if (end > best_end) {
                        best_start = buffer.getSpanStart(candidate1);
                        best_end = end;
                    }
                }
            }

            if (best_start >= 0) {
                Selection.setSelection(buffer, best_end, best_start);
                return true;
            }

            break;

        case DOWN:
            best_start = Integer.MAX_VALUE;
            best_end = Integer.MAX_VALUE;

            for (MyURLSpan candidate : candidates) {
                int start = buffer.getSpanStart(candidate);

                if (start > selStart || selStart == selEnd) {
                    if (start < best_start) {
                        best_start = start;
                        best_end = buffer.getSpanEnd(candidate);
                    }
                }
            }

            if (best_end < Integer.MAX_VALUE) {
                Selection.setSelection(buffer, best_start, best_end);
                return true;
            }

            break;
    }

    return false;
}
 
Example 16
Source File: LocaleSpanCompatUtils.java    From AOSP-Kayboard-7.1.2 with Apache License 2.0 4 votes vote down vote up
/**
 * Ensures that the specified range is covered with only one {@link LocaleSpan} with the given
 * locale. If the region is already covered by one or more {@link LocaleSpan}, their ranges are
 * updated so that each character has only one locale.
 * @param spannable the spannable object to be updated.
 * @param start the start index from which {@link LocaleSpan} is attached (inclusive).
 * @param end the end index to which {@link LocaleSpan} is attached (exclusive).
 * @param locale the locale to be attached to the specified range.
 */
@UsedForTesting
public static void updateLocaleSpan(final Spannable spannable, final int start,
        final int end, final Locale locale) {
    if (end < start) {
        Log.e(TAG, "Invalid range: start=" + start + " end=" + end);
        return;
    }
    if (!isLocaleSpanAvailable()) {
        return;
    }
    // A brief summary of our strategy;
    //   1. Enumerate all LocaleSpans between [start - 1, end + 1].
    //   2. For each LocaleSpan S:
    //      - Update the range of S so as not to cover [start, end] if S doesn't have the
    //        expected locale.
    //      - Mark S as "to be merged" if S has the expected locale.
    //   3. Merge all the LocaleSpans that are marked as "to be merged" into one LocaleSpan.
    //      If no appropriate span is found, create a new one with newLocaleSpan method.
    final int searchStart = Math.max(start - 1, 0);
    final int searchEnd = Math.min(end + 1, spannable.length());
    // LocaleSpans found in the target range. See the step 1 in the above comment.
    final Object[] existingLocaleSpans = spannable.getSpans(searchStart, searchEnd,
            LOCALE_SPAN_TYPE);
    // LocaleSpans that are marked as "to be merged". See the step 2 in the above comment.
    final ArrayList<Object> existingLocaleSpansToBeMerged = new ArrayList<>();
    boolean isStartExclusive = true;
    boolean isEndExclusive = true;
    int newStart = start;
    int newEnd = end;
    for (final Object existingLocaleSpan : existingLocaleSpans) {
        final Locale attachedLocale = getLocaleFromLocaleSpan(existingLocaleSpan);
        if (!locale.equals(attachedLocale)) {
            // This LocaleSpan does not have the expected locale. Update its range if it has
            // an intersection with the range [start, end] (the first case of the step 2 in the
            // above comment).
            removeLocaleSpanFromRange(existingLocaleSpan, spannable, start, end);
            continue;
        }
        final int spanStart = spannable.getSpanStart(existingLocaleSpan);
        final int spanEnd = spannable.getSpanEnd(existingLocaleSpan);
        if (spanEnd < spanStart) {
            Log.e(TAG, "Invalid span: spanStart=" + spanStart + " spanEnd=" + spanEnd);
            continue;
        }
        if (spanEnd < start || end < spanStart) {
            // No intersection found.
            continue;
        }

        // Here existingLocaleSpan has the expected locale and an intersection with the
        // range [start, end] (the second case of the the step 2 in the above comment).
        final int spanFlag = spannable.getSpanFlags(existingLocaleSpan);
        if (spanStart < newStart) {
            newStart = spanStart;
            isStartExclusive = ((spanFlag & Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) ==
                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
        if (newEnd < spanEnd) {
            newEnd = spanEnd;
            isEndExclusive = ((spanFlag & Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) ==
                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
        existingLocaleSpansToBeMerged.add(existingLocaleSpan);
    }

    int originalLocaleSpanFlag = 0;
    Object localeSpan = null;
    if (existingLocaleSpansToBeMerged.isEmpty()) {
        // If there is no LocaleSpan that is marked as to be merged, create a new one.
        localeSpan = newLocaleSpan(locale);
    } else {
        // Reuse the first LocaleSpan to avoid unnecessary object instantiation.
        localeSpan = existingLocaleSpansToBeMerged.get(0);
        originalLocaleSpanFlag = spannable.getSpanFlags(localeSpan);
        // No need to keep other instances.
        for (int i = 1; i < existingLocaleSpansToBeMerged.size(); ++i) {
            spannable.removeSpan(existingLocaleSpansToBeMerged.get(i));
        }
    }
    final int localeSpanFlag = getSpanFlag(originalLocaleSpanFlag, isStartExclusive,
            isEndExclusive);
    spannable.setSpan(localeSpan, newStart, newEnd, localeSpanFlag);
}
 
Example 17
Source File: UrlImageGetter.java    From android-discourse with Apache License 2.0 4 votes vote down vote up
@Override
protected void onPostExecute(Drawable result) {
    if (result == null) {
        // TODO 设置默认错误图片?
        return;
    }
    // set the correct bound according to the result from HTTP call
    int w = result.getIntrinsicWidth();
    int h = result.getIntrinsicHeight();
    urlDrawable.setBounds(0, 0, 0 + w, 0 + h);
    L.i("%d X %d", w, h);

    // change the reference of the current drawable to the result
    // from the HTTP call
    urlDrawable.drawable = result;

    // redraw the image by invalidating the container
    // 由于下面重新设置了ImageSpan,所以这里invalidate就不必要了吧
    // urlDrawable.invalidateSelf();
    // UrlImageGetter.this.mTextView.invalidate();

    // TODO 这种方式基本完美解决显示图片问题, blog?
    // 把提取到下面显示的图片在放出来? 然后点击任何图片 进入到 帖子图片浏览界面。。?
    TextView v = UrlImageGetter.this.mTextView;
    Spannable spanText = (Spannable) v.getText();
    @SuppressWarnings("unchecked") ArrayList<String> imgs = (ArrayList<String>) v.getTag(R.id.poste_image_data);
    ImageSpan[] imageSpans = spanText.getSpans(0, spanText.length(), ImageSpan.class);
    for (ImageSpan imgSpan : imageSpans) {
        int start = spanText.getSpanStart(imgSpan);
        int end = spanText.getSpanEnd(imgSpan);
        L.i("%d-%d :%s", start, end, imgSpan.getSource());
        if (src.equals(imgSpan.getSource())) {
            spanText.removeSpan(imgSpan);
            ImageSpan is = new ImageSpan(result, src, ImageSpan.ALIGN_BASELINE);
            spanText.setSpan(is, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
        if (imgs != null && imgs.contains(src)) {
            ImageClickableSpan ics = new ImageClickableSpan(src);
            spanText.setSpan(ics, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        }

    }
    // For ICS
    // UrlImageGetter.this.container.setMinimumHeight(
    // (UrlImageGetter.this.container.getHeight() + result.getIntrinsicHeight()));
    // UrlImageGetter.this.container.requestLayout();
    // UrlImageGetter.this.container.invalidate();
}
 
Example 18
Source File: WeiboTextView.java    From BigApp_Discuz_Android with Apache License 2.0 4 votes vote down vote up
@Override
        public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
            int action = event.getAction();

//            LogUtils.printLog(WeiboTextView.class, "MotionEvent:" + action);

//            if (action == MotionEvent.ACTION_MOVE) {
//                isPressed = false;
//            }
            switch (action) {
                case MotionEvent.ACTION_DOWN:
                    break;
                case MotionEvent.ACTION_UP:
                    break;

                case MotionEvent.ACTION_CANCEL:
                    buffer.setSpan(new BackgroundColorSpan(0x00000000), 0, weiboTextView.length(),
                            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                    Selection.setSelection(buffer, 0, weiboTextView.length());
                    break;
            }


            if (action == MotionEvent.ACTION_UP ||
                    action == MotionEvent.ACTION_DOWN) {
                int x = (int) event.getX();
                int y = (int) event.getY();

                x -= widget.getTotalPaddingLeft();
                y -= widget.getTotalPaddingTop();

                x += widget.getScrollX();
                y += widget.getScrollY();

                Layout layout = widget.getLayout();
                int line = layout.getLineForVertical(y);
                int off = layout.getOffsetForHorizontal(line, x);

                ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);

                if (link.length != 0) {

                    int start = buffer.getSpanStart(link[0]);
                    int end = buffer.getSpanEnd(link[0]);

//                    LogUtils.printLog(WebViewUtils.class, "start:" + start + " end:" + end);

                    if (action == MotionEvent.ACTION_UP) {
                        link[0].onClick(widget);
                        buffer.setSpan(new BackgroundColorSpan(0x00000000), start, end,
                                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                        Selection.setSelection(buffer, start, end);
                    } else if (action == MotionEvent.ACTION_DOWN) {
                        buffer.setSpan(new BackgroundColorSpan(weiboTextView.clickBgClolr), start, end,
                                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                        Selection.setSelection(buffer, start, end);
                    }

                    if (widget instanceof WeiboTextView) {
                        ((WeiboTextView) widget).linkHit = true;
                    }
                    return true;
                } else {
                    Selection.removeSelection(buffer);
                    Touch.onTouchEvent(widget, buffer, event);
                    return false;
                }
            }


            return Touch.onTouchEvent(widget, buffer, event);
        }
 
Example 19
Source File: BaseInputConnection.java    From android_9.0.0_r45 with Apache License 2.0 4 votes vote down vote up
public static int getComposingSpanEnd(Spannable text) {
    return text.getSpanEnd(COMPOSING);
}
 
Example 20
Source File: LongClickableLinkMovementMethod.java    From iBeebo with GNU General Public License v3.0 4 votes vote down vote up
private boolean action(int what, TextView widget, Spannable buffer) {
    Layout layout = widget.getLayout();

    int padding = widget.getTotalPaddingTop() + widget.getTotalPaddingBottom();
    int areatop = widget.getScrollY();
    int areabot = areatop + widget.getHeight() - padding;

    int linetop = layout.getLineForVertical(areatop);
    int linebot = layout.getLineForVertical(areabot);

    int first = layout.getLineStart(linetop);
    int last = layout.getLineEnd(linebot);

    MyURLSpan[] candidates = buffer.getSpans(first, last, MyURLSpan.class);

    int a = Selection.getSelectionStart(buffer);
    int b = Selection.getSelectionEnd(buffer);

    int selStart = Math.min(a, b);
    int selEnd = Math.max(a, b);

    if (selStart < 0) {
        if (buffer.getSpanStart(FROM_BELOW) >= 0) {
            selStart = selEnd = buffer.length();
        }
    }

    if (selStart > last) {
        selStart = selEnd = Integer.MAX_VALUE;
    }
    if (selEnd < first) {
        selStart = selEnd = -1;
    }

    switch (what) {
        case CLICK:
            if (selStart == selEnd) {
                return false;
            }

            MyURLSpan[] link = buffer.getSpans(selStart, selEnd, MyURLSpan.class);

            if (link.length != 1) {
                return false;
            }

            link[0].onClick(widget);
            break;

        case UP:
            int best_start = -1;
            int best_end = -1;

            for (MyURLSpan candidate1 : candidates) {
                int end = buffer.getSpanEnd(candidate1);

                if (end < selEnd || selStart == selEnd) {
                    if (end > best_end) {
                        best_start = buffer.getSpanStart(candidate1);
                        best_end = end;
                    }
                }
            }

            if (best_start >= 0) {
                Selection.setSelection(buffer, best_end, best_start);
                return true;
            }

            break;

        case DOWN:
            best_start = Integer.MAX_VALUE;
            best_end = Integer.MAX_VALUE;

            for (MyURLSpan candidate : candidates) {
                int start = buffer.getSpanStart(candidate);

                if (start > selStart || selStart == selEnd) {
                    if (start < best_start) {
                        best_start = start;
                        best_end = buffer.getSpanEnd(candidate);
                    }
                }
            }

            if (best_end < Integer.MAX_VALUE) {
                Selection.setSelection(buffer, best_start, best_end);
                return true;
            }

            break;
    }

    return false;
}