Example usage for android.text Spannable removeSpan

List of usage examples for android.text Spannable removeSpan

Introduction

In this page you can find the example usage for android.text Spannable removeSpan.

Prototype

public void removeSpan(Object what);

Source Link

Document

Remove the specified object from the range of text to which it was attached, if any.

Usage

From source file:com.hippo.nimingban.ui.ListActivity.java

private Spanned fixURLSpan(Spanned spanned) {
    Spannable spannable;
    if (spanned instanceof Spannable) {
        spannable = (Spannable) spanned;
    } else {// w w w .j  a  v  a  2s.  c o  m
        spannable = new SpannableString(spanned);
    }

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

    for (URLSpan urlSpan : urlSpans) {
        String url = urlSpan.getURL();
        if (TextUtils.isEmpty(url)) {
            spannable.removeSpan(urlSpan);
        }

        try {
            new URL(url);
        } catch (MalformedURLException e) {
            URL absoluteUrl;
            // It might be relative path
            try {
                // Use absolute url
                absoluteUrl = new URL(new URL(ACUrl.HOST), url);
                int start = spannable.getSpanStart(urlSpan);
                int end = spannable.getSpanEnd(urlSpan);
                spannable.removeSpan(urlSpan);
                spannable.setSpan(new URLSpan(absoluteUrl.toString()), start, end,
                        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            } catch (MalformedURLException e1) {
                // Can't get url
                spannable.removeSpan(urlSpan);
            }
        }
    }

    return spannable;
}

From source file:org.proninyaroslav.libretorrent.fragments.DetailTorrentFragment.java

@Override
public void onShow(final AlertDialog dialog) {
    if (dialog == null) {
        return;//  w ww.ja v a  2 s .  c  o m
    }

    if (getFragmentManager().findFragmentByTag(TAG_ADD_TRACKERS_DIALOG) != null) {
        final TextInputEditText field = (TextInputEditText) dialog
                .findViewById(R.id.multiline_text_input_dialog);
        final TextInputLayout fieldLayout = (TextInputLayout) dialog
                .findViewById(R.id.layout_multiline_text_input_dialog);

        /* Dismiss error label if user has changed the text */
        if (field != null && fieldLayout != null) {
            field.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                    /* Nothing */
                }

                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {
                    fieldLayout.setErrorEnabled(false);
                    fieldLayout.setError(null);

                    /* Clear selection of invalid url */
                    Spannable text = field.getText();
                    ForegroundColorSpan[] errorSpans = text.getSpans(0, text.length(),
                            ForegroundColorSpan.class);
                    for (ForegroundColorSpan span : errorSpans) {
                        text.removeSpan(span);
                    }
                }

                @Override
                public void afterTextChanged(Editable s) {
                    /* Nothing */
                }
            });
        }

        /*
         * It is necessary in order to the dialog is not closed by
         * pressing add/replace button if the text checker gave a false result
         */
        Button addButton = dialog.getButton(AlertDialog.BUTTON_POSITIVE);
        Button replaceButton = dialog.getButton(AlertDialog.BUTTON_NEGATIVE);

        addButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (field != null && fieldLayout != null) {
                    String text = field.getText().toString();
                    List<String> urls = Arrays.asList(text.split(Utils.getLineSeparator()));

                    if (checkEditTextField(urls, fieldLayout, field)) {
                        addTrackersRequest(new ArrayList<>(urls), false);

                        dialog.dismiss();
                    }
                }
            }
        });

        replaceButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (field != null && fieldLayout != null) {
                    String text = field.getText().toString();
                    List<String> urls = Arrays.asList(text.split(Utils.getLineSeparator()));

                    if (checkEditTextField(urls, fieldLayout, field)) {
                        addTrackersRequest(new ArrayList<>(urls), true);

                        dialog.dismiss();
                    }
                }
            }
        });

        /* Inserting links from the clipboard */
        String clipboard = Utils.getClipboard(activity.getApplicationContext());

        if (clipboard != null && field != null) {
            List<String> urls = Arrays.asList(clipboard.split(Utils.getLineSeparator()));
            ArrayList<String> validUrls = new ArrayList<>();

            for (String url : urls) {
                if (Utils.isValidTrackerUrl(url)) {
                    validUrls.add(url);
                }
            }

            field.setText(TextUtils.join(Utils.getLineSeparator(), validUrls));
        }

    } else if (getFragmentManager().findFragmentByTag(TAG_SPEED_LIMIT_DIALOG) != null) {
        TextInputEditText upload = (TextInputEditText) dialog.findViewById(R.id.upload_limit);
        TextInputEditText download = (TextInputEditText) dialog.findViewById(R.id.download_limit);

        if (upload != null && download != null) {
            int minSpeedLimit = 0;
            int maxSpeedLimit = Integer.MAX_VALUE;
            InputFilter[] filter = new InputFilter[] { new InputFilterMinMax(minSpeedLimit, maxSpeedLimit) };

            upload.setFilters(filter);
            if (TextUtils.isEmpty(upload.getText())) {
                upload.setText((uploadSpeedLimit != -1 ? Integer.toString(uploadSpeedLimit / 1024)
                        : Integer.toString(minSpeedLimit)));
            }

            download.setFilters(filter);
            if (TextUtils.isEmpty(download.getText())) {
                download.setText((downloadSpeedLimit != -1 ? Integer.toString(downloadSpeedLimit / 1024)
                        : Integer.toString(minSpeedLimit)));
            }
        }
    }
}

From source file:com.tct.mail.browse.MessageHeaderView.java

private void stripUnderlines(TextView textView, Account account) {
    final Spannable spannable = (Spannable) textView.getText();
    final URLSpan[] urls = textView.getUrls();

    for (URLSpan span : urls) {
        final int start = spannable.getSpanStart(span);
        final int end = spannable.getSpanEnd(span);
        spannable.removeSpan(span);
        //TS: rong-tang 2016-04-19 EMAIL BUGFIX-1951808 MOD_S
        span = new EmailAddressSpan(getContext(), account, span.getURL().substring(7), mContactInfoSource);
        ((EmailAddressSpan) span).setFragmentManager(mFragmentManager);
        //TS: rong-tang 2016-04-19 EMAIL BUGFIX-1951808 MOD_E
        spannable.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    }/*w  ww. j av  a  2  s  .  c om*/
}

From source file:android.support.text.emoji.EmojiProcessor.java

/**
 * Checks a given CharSequence for emojis, and adds EmojiSpans if any emojis are found.
 * <p>//from  w w w  .  j  a va  2 s .c o  m
 * <ul>
 * <li>If no emojis are found, {@code charSequence} given as the input is returned without
 * any changes. i.e. charSequence is a String, and no emojis are found, the same String is
 * returned.</li>
 * <li>If the given input is not a Spannable (such as String), and at least one emoji is found
 * a new {@link android.text.Spannable} instance is returned. </li>
 * <li>If the given input is a Spannable, the same instance is returned. </li>
 * </ul>
 *
 * @param charSequence CharSequence to add the EmojiSpans, cannot be {@code null}
 * @param start start index in the charSequence to look for emojis, should be greater than or
 *              equal to {@code 0}, also less than {@code charSequence.length()}
 * @param end end index in the charSequence to look for emojis, should be greater than or
 *            equal to {@code start} parameter, also less than {@code charSequence.length()}
 * @param maxEmojiCount maximum number of emojis in the {@code charSequence}, should be greater
 *                      than or equal to {@code 0}
 * @param replaceAll whether to replace all emoji with {@link EmojiSpan}s
 */
CharSequence process(@NonNull final CharSequence charSequence, @IntRange(from = 0) int start,
        @IntRange(from = 0) int end, @IntRange(from = 0) int maxEmojiCount, final boolean replaceAll) {
    final boolean isSpannableBuilder = charSequence instanceof SpannableBuilder;
    if (isSpannableBuilder) {
        ((SpannableBuilder) charSequence).beginBatchEdit();
    }

    try {
        Spannable spannable = null;
        // if it is a spannable already, use the same instance to add/remove EmojiSpans.
        // otherwise wait until the the first EmojiSpan found in order to change the result
        // into a Spannable.
        if (isSpannableBuilder || charSequence instanceof Spannable) {
            spannable = (Spannable) charSequence;
        }

        if (spannable != null) {
            final EmojiSpan[] spans = spannable.getSpans(start, end, EmojiSpan.class);
            if (spans != null && spans.length > 0) {
                // remove existing spans, and realign the start, end according to spans
                // if start or end is in the middle of an emoji they should be aligned
                final int length = spans.length;
                for (int index = 0; index < length; index++) {
                    final EmojiSpan span = spans[index];
                    final int spanStart = spannable.getSpanStart(span);
                    final int spanEnd = spannable.getSpanEnd(span);
                    // Remove span only when its spanStart is NOT equal to current end.
                    // During add operation an emoji at index 0 is added with 0-1 as start and
                    // end indices. Therefore if there are emoji spans at [0-1] and [1-2]
                    // and end is 1, the span between 0-1 should be deleted, not 1-2.
                    if (spanStart != end) {
                        spannable.removeSpan(span);
                    }
                    start = Math.min(spanStart, start);
                    end = Math.max(spanEnd, end);
                }
            }
        }

        if (start == end || start >= charSequence.length()) {
            return charSequence;
        }

        // calculate max number of emojis that can be added. since getSpans call is a relatively
        // expensive operation, do it only when maxEmojiCount is not unlimited.
        if (maxEmojiCount != EmojiCompat.EMOJI_COUNT_UNLIMITED && spannable != null) {
            maxEmojiCount -= spannable.getSpans(0, spannable.length(), EmojiSpan.class).length;
        }
        // add new ones
        int addedCount = 0;
        final ProcessorSm sm = new ProcessorSm(mMetadataRepo.getRootNode());

        int currentOffset = start;
        int codePoint = Character.codePointAt(charSequence, currentOffset);

        while (currentOffset < end && addedCount < maxEmojiCount) {
            final int action = sm.check(codePoint);

            switch (action) {
            case ACTION_ADVANCE_BOTH:
                start += Character.charCount(Character.codePointAt(charSequence, start));
                currentOffset = start;
                if (currentOffset < end) {
                    codePoint = Character.codePointAt(charSequence, currentOffset);
                }
                break;
            case ACTION_ADVANCE_END:
                currentOffset += Character.charCount(codePoint);
                if (currentOffset < end) {
                    codePoint = Character.codePointAt(charSequence, currentOffset);
                }
                break;
            case ACTION_FLUSH:
                if (replaceAll || !hasGlyph(charSequence, start, currentOffset, sm.getFlushMetadata())) {
                    if (spannable == null) {
                        spannable = new SpannableString(charSequence);
                    }
                    addEmoji(spannable, sm.getFlushMetadata(), start, currentOffset);
                    addedCount++;
                }
                start = currentOffset;
                break;
            }
        }

        // After the last codepoint is consumed the state machine might be in a state where it
        // identified an emoji before. i.e. abc[women-emoji] when the last codepoint is consumed
        // state machine is waiting to see if there is an emoji sequence (i.e. ZWJ).
        // Need to check if it is in such a state.
        if (sm.isInFlushableState() && addedCount < maxEmojiCount) {
            if (replaceAll || !hasGlyph(charSequence, start, currentOffset, sm.getCurrentMetadata())) {
                if (spannable == null) {
                    spannable = new SpannableString(charSequence);
                }
                addEmoji(spannable, sm.getCurrentMetadata(), start, currentOffset);
                addedCount++;
            }
        }
        return spannable == null ? charSequence : spannable;
    } finally {
        if (isSpannableBuilder) {
            ((SpannableBuilder) charSequence).endBatchEdit();
        }
    }
}

From source file:com.android.ex.chips.RecipientEditTextView.java

/**
 * Replace the more chip, if it exists, with all of the recipient chips it had replaced when the
 * RecipientEditTextView gains focus./*from ww w  .java2  s.  c  om*/
 */
// Visible for testing.
/* package */void removeMoreChip() {
    if (mMoreChip != null) {
        final 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.
            final 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]);
            final Editable editable = getText();
            for (final 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, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
            mRemovedSpans.clear();
        }
    }
}

From source file:com.android.ex.chips.RecipientEditTextView.java

/**
 * Show specified chip as selected. If the RecipientChip is just an email address, selecting the chip will take the
 * contents of the chip and place it at the end of the RecipientEditTextView for inline editing. If the
 * RecipientChip is a complete contact, then selecting the chip will change the background color of the chip, show
 * the delete icon, and a popup window with the address in use highlighted and any other alternate addresses for the
 * contact./*  www. j ava 2s. c  o  m*/
 *
 * @param currentChip
 * Chip to select.
 * @return A RecipientChip in the selected state or null if the chip just contained an email address.
 */
private DrawableRecipientChip selectChip(final DrawableRecipientChip currentChip) {
    if (shouldShowEditableText(currentChip)) {
        final CharSequence text = currentChip.getValue();
        final Editable editable = getText();
        final Spannable spannable = getSpannable();
        final int spanStart = spannable.getSpanStart(currentChip);
        final int spanEnd = spannable.getSpanEnd(currentChip);
        spannable.removeSpan(currentChip);
        editable.delete(spanStart, spanEnd);
        setCursorVisible(true);
        setSelection(editable.length());
        editable.append(text);
        return constructChipSpan(RecipientEntry.constructFakeEntry((String) text, isValid(text.toString())),
                true, false);
    } else if (currentChip.getContactId() == RecipientEntry.GENERATED_CONTACT || currentChip.isGalContact()) {
        final int start = getChipStart(currentChip);
        final int end = getChipEnd(currentChip);
        getSpannable().removeSpan(currentChip);
        DrawableRecipientChip newChip;
        try {
            if (mNoChips)
                return null;
            newChip = constructChipSpan(currentChip.getEntry(), true, false);
        } catch (final NullPointerException e) {
            Log.e(TAG, e.getMessage(), e);
            return null;
        }
        final Editable editable = getText();
        QwertyKeyListener.markAsReplaced(editable, start, end, "");
        if (start == -1 || end == -1)
            Log.d(TAG, "The chip being selected no longer exists but should.");
        else
            editable.setSpan(newChip, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        newChip.setSelected(true);
        if (shouldShowEditableText(newChip))
            scrollLineIntoView(getLayout().getLineForOffset(getChipStart(newChip)));
        //showAddress(newChip,mAddressPopup,getWidth());
        setCursorVisible(false);
        return newChip;
    } else {
        final int start = getChipStart(currentChip);
        final int end = getChipEnd(currentChip);
        getSpannable().removeSpan(currentChip);
        DrawableRecipientChip newChip;
        try {
            newChip = constructChipSpan(currentChip.getEntry(), true, false);
        } catch (final NullPointerException e) {
            Log.e(TAG, e.getMessage(), e);
            return null;
        }
        final Editable editable = getText();
        QwertyKeyListener.markAsReplaced(editable, start, end, "");
        if (start == -1 || end == -1)
            Log.d(TAG, "The chip being selected no longer exists but should.");
        else
            editable.setSpan(newChip, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        newChip.setSelected(true);
        if (shouldShowEditableText(newChip))
            scrollLineIntoView(getLayout().getLineForOffset(getChipStart(newChip)));
        //showAlternates(newChip,mAlternatesPopup,getWidth());
        setCursorVisible(false);
        return newChip;
    }
}

From source file:com.android.ex.chips.RecipientEditTextView.java

/**
 * Remove the chip and any text associated with it from the RecipientEditTextView.
 *
 * @param alsoNotifyAboutDataChanges/*from   w  ww.  j  av a2s  .  c om*/
 */
// Visible for testing.
/* package */void removeChip(final DrawableRecipientChip chip, final boolean alsoNotifyAboutDataChanges) {
    if (!alsoNotifyAboutDataChanges)
        --mPreviousChipsCount;
    final Spannable spannable = getSpannable();
    final int spanStart = spannable.getSpanStart(chip);
    final int spanEnd = spannable.getSpanEnd(chip);
    final Editable text = getText();
    int toDelete = spanEnd;
    final 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();
}

From source file:com.android.ex.chips.RecipientEditTextView.java

/**
 * Create the more chip. The more chip is text that replaces any chips that do not fit in the pre-defined available
 * space when the RecipientEditTextView loses focus.
 *//*from ww  w . ja  v  a  2  s  . c o  m*/
// Visible for testing.
/* package */void createMoreChip() {
    if (mNoChips) {
        createMoreChipPlainText();
        return;
    }
    if (!mShouldShrink)
        return;
    final ImageSpan[] tempMore = getSpannable().getSpans(0, getText().length(), MoreImageSpan.class);
    if (tempMore.length > 0)
        getSpannable().removeSpan(tempMore[0]);
    final DrawableRecipientChip[] recipients = getSortedRecipients();
    if (recipients == null || recipients.length <= CHIP_LIMIT) {
        mMoreChip = null;
        return;
    }
    final Spannable spannable = getSpannable();
    final int numRecipients = recipients.length;
    final int overage = numRecipients - CHIP_LIMIT;
    final MoreImageSpan moreSpan = createMoreSpan(overage);
    mRemovedSpans = new ArrayList<DrawableRecipientChip>();
    int totalReplaceStart = 0;
    int totalReplaceEnd = 0;
    final Editable text = getText();
    for (int i = numRecipients - overage; i < recipients.length; i++) {
        mRemovedSpans.add(recipients[i]);
        if (i == numRecipients - overage)
            totalReplaceStart = spannable.getSpanStart(recipients[i]);
        if (i == recipients.length - 1)
            totalReplaceEnd = spannable.getSpanEnd(recipients[i]);
        if (mTemporaryRecipients == null || !mTemporaryRecipients.contains(recipients[i])) {
            final int spanStart = spannable.getSpanStart(recipients[i]);
            final int spanEnd = spannable.getSpanEnd(recipients[i]);
            recipients[i].setOriginalText(text.toString().substring(spanStart, spanEnd));
        }
        spannable.removeSpan(recipients[i]);
    }
    if (totalReplaceEnd < text.length())
        totalReplaceEnd = text.length();
    final int end = Math.max(totalReplaceStart, totalReplaceEnd);
    final int start = Math.min(totalReplaceStart, totalReplaceEnd);
    final SpannableString chipText = new SpannableString(text.subSequence(start, end));
    chipText.setSpan(moreSpan, 0, chipText.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    text.replace(start, end, chipText);
    mMoreChip = moreSpan;
    // If adding the +more chip goes over the limit, resize accordingly.
    if (!isPhoneQuery() && getLineCount() > mMaxLines)
        setMaxLines(getLineCount());
}