Search in sources :

Example 56 with Spannable

use of android.text.Spannable in project FlexibleAdapter by davideas.

the class Utils method highlightText.

/**
	 * Sets a spannable text with the accent color (if available) into the provided TextView.
	 * <p>Internally calls {@link #fetchAccentColor(Context, int)}.</p>
	 *
	 * @param context      context
	 * @param textView     the TextView to transform
	 * @param originalText the original text which the transformation is applied to
	 * @param constraint   the text to highlight
	 * @param defColor     the default color in case accentColor is not found
	 * @see #fetchAccentColor(Context, int)
	 * @deprecated Use
	 * {@link #highlightText(TextView, String, String, int)} OR
	 * {@link #highlightText(TextView, String, String)}
	 */
@Deprecated
public static void highlightText(@NonNull Context context, @NonNull TextView textView, String originalText, String constraint, @ColorInt int defColor) {
    if (originalText == null)
        originalText = "";
    if (constraint == null)
        constraint = "";
    int i = originalText.toLowerCase(Locale.getDefault()).indexOf(constraint.toLowerCase(Locale.getDefault()));
    if (i != -1) {
        Spannable spanText = Spannable.Factory.getInstance().newSpannable(originalText);
        spanText.setSpan(new ForegroundColorSpan(fetchAccentColor(context, defColor)), i, i + constraint.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        spanText.setSpan(new StyleSpan(Typeface.BOLD), i, i + constraint.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        textView.setText(spanText, TextView.BufferType.SPANNABLE);
    } else {
        textView.setText(originalText, TextView.BufferType.NORMAL);
    }
}
Also used : ForegroundColorSpan(android.text.style.ForegroundColorSpan) StyleSpan(android.text.style.StyleSpan) SuppressLint(android.annotation.SuppressLint) Spannable(android.text.Spannable)

Example 57 with Spannable

use of android.text.Spannable in project Etar-Calendar by Etar-Group.

the class Utils method extendedLinkify.

/**
     * Replaces stretches of text that look like addresses and phone numbers with clickable
     * links. If lastDitchGeo is true, then if no links are found in the textview, the entire
     * string will be converted to a single geo link. Any spans that may have previously been
     * in the text will be cleared out.
     * <p>
     * This is really just an enhanced version of Linkify.addLinks().
     *
     * @param text - The string to search for links.
     * @param lastDitchGeo - If no links are found, turn the entire string into one geo link.
     * @return Spannable object containing the list of URL spans found.
     */
public static Spannable extendedLinkify(String text, boolean lastDitchGeo) {
    // We use a copy of the string argument so it's available for later if necessary.
    Spannable spanText = SpannableString.valueOf(text);
    /*
         * If the text includes a street address like "1600 Amphitheater Parkway, 94043",
         * the current Linkify code will identify "94043" as a phone number and invite
         * you to dial it (and not provide a map link for the address).  For outside US,
         * use Linkify result iff it spans the entire text.  Otherwise send the user to maps.
         */
    String defaultPhoneRegion = System.getProperty("user.region", "US");
    if (!defaultPhoneRegion.equals("US")) {
        Linkify.addLinks(spanText, Linkify.ALL);
        // If Linkify links the entire text, use that result.
        URLSpan[] spans = spanText.getSpans(0, spanText.length(), URLSpan.class);
        if (spans.length == 1) {
            int linkStart = spanText.getSpanStart(spans[0]);
            int linkEnd = spanText.getSpanEnd(spans[0]);
            if (linkStart <= indexFirstNonWhitespaceChar(spanText) && linkEnd >= indexLastNonWhitespaceChar(spanText) + 1) {
                return spanText;
            }
        }
        // Otherwise, to be cautious and to try to prevent false positives, reset the spannable.
        spanText = SpannableString.valueOf(text);
        // If lastDitchGeo is true, default the entire string to geo.
        if (lastDitchGeo && !text.isEmpty()) {
            Linkify.addLinks(spanText, mWildcardPattern, "geo:0,0?q=");
        }
        return spanText;
    }
    /*
         * For within US, we want to have better recognition of phone numbers without losing
         * any of the existing annotations.  Ideally this would be addressed by improving Linkify.
         * For now we manage it as a second pass over the text.
         *
         * URIs and e-mail addresses are pretty easy to pick out of text.  Phone numbers
         * are a bit tricky because they have radically different formats in different
         * countries, in terms of both the digits and the way in which they are commonly
         * written or presented (e.g. the punctuation and spaces in "(650) 555-1212").
         * The expected format of a street address is defined in WebView.findAddress().  It's
         * pretty narrowly defined, so it won't often match.
         *
         * The RFC 3966 specification defines the format of a "tel:" URI.
         *
         * Start by letting Linkify find anything that isn't a phone number.  We have to let it
         * run first because every invocation removes all previous URLSpan annotations.
         *
         * Ideally we'd use the external/libphonenumber routines, but those aren't available
         * to unbundled applications.
         */
    boolean linkifyFoundLinks = Linkify.addLinks(spanText, Linkify.ALL & ~(Linkify.PHONE_NUMBERS));
    /*
         * Get a list of any spans created by Linkify, for the coordinate overlapping span check.
         */
    URLSpan[] existingSpans = spanText.getSpans(0, spanText.length(), URLSpan.class);
    /*
         * Check for coordinates.
         * This must be done before phone numbers because longitude may look like a phone number.
         */
    Matcher coordMatcher = COORD_PATTERN.matcher(spanText);
    int coordCount = 0;
    while (coordMatcher.find()) {
        int start = coordMatcher.start();
        int end = coordMatcher.end();
        if (spanWillOverlap(spanText, existingSpans, start, end)) {
            continue;
        }
        URLSpan span = new URLSpan("geo:0,0?q=" + coordMatcher.group());
        spanText.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        coordCount++;
    }
    /*
         * Update the list of existing spans, for the phone number overlapping span check.
         */
    existingSpans = spanText.getSpans(0, spanText.length(), URLSpan.class);
    /*
         * Search for phone numbers.
         *
         * Some URIs contain strings of digits that look like phone numbers.  If both the URI
         * scanner and the phone number scanner find them, we want the URI link to win.  Since
         * the URI scanner runs first, we just need to avoid creating overlapping spans.
         */
    int[] phoneSequences = findNanpPhoneNumbers(text);
    /*
         * Insert spans for the numbers we found.  We generate "tel:" URIs.
         */
    int phoneCount = 0;
    for (int match = 0; match < phoneSequences.length / 2; match++) {
        int start = phoneSequences[match * 2];
        int end = phoneSequences[match * 2 + 1];
        if (spanWillOverlap(spanText, existingSpans, start, end)) {
            continue;
        }
        /*
             * The Linkify code takes the matching span and strips out everything that isn't a
             * digit or '+' sign.  We do the same here.  Extension numbers will get appended
             * without a separator, but the dialer wasn't doing anything useful with ";ext="
             * anyway.
             */
        //String dialStr = phoneUtil.format(match.number(),
        //        PhoneNumberUtil.PhoneNumberFormat.RFC3966);
        StringBuilder dialBuilder = new StringBuilder();
        for (int i = start; i < end; i++) {
            char ch = spanText.charAt(i);
            if (ch == '+' || Character.isDigit(ch)) {
                dialBuilder.append(ch);
            }
        }
        URLSpan span = new URLSpan("tel:" + dialBuilder.toString());
        spanText.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        phoneCount++;
    }
    /*
         * If lastDitchGeo, and no other links have been found, set the entire string as a geo link.
         */
    if (lastDitchGeo && !text.isEmpty() && !linkifyFoundLinks && phoneCount == 0 && coordCount == 0) {
        if (Log.isLoggable(TAG, Log.VERBOSE)) {
            Log.v(TAG, "No linkification matches, using geo default");
        }
        Linkify.addLinks(spanText, mWildcardPattern, "geo:0,0?q=");
    }
    return spanText;
}
Also used : Matcher(java.util.regex.Matcher) SpannableString(android.text.SpannableString) URLSpan(android.text.style.URLSpan) Spannable(android.text.Spannable)

Example 58 with Spannable

use of android.text.Spannable in project Etar-Calendar by Etar-Group.

the class AlertReceiver method getURLSpans.

/**
     * Using the linkify magic, get a list of URLs from the event's location. If no such links
     * are found, we should end up with a single geo link of the entire string.
     */
private static URLSpan[] getURLSpans(Context context, long eventId) {
    Cursor locationCursor = getLocationCursor(context, eventId);
    if (locationCursor != null && locationCursor.moveToFirst()) {
        // Only one item in this cursor.
        String location = locationCursor.getString(0);
        if (location == null || location.isEmpty()) {
            // Return an empty list if we know there was nothing in the location field.
            return new URLSpan[0];
        }
        Spannable text = Utils.extendedLinkify(location, true);
        // The linkify method should have found at least one link, at the very least.
        // If no smart links were found, it should have set the whole string as a geo link.
        URLSpan[] urlSpans = text.getSpans(0, text.length(), URLSpan.class);
        return urlSpans;
    }
    // If no links were found or location was empty, return an empty list.
    return new URLSpan[0];
}
Also used : Cursor(android.database.Cursor) URLSpan(android.text.style.URLSpan) Spannable(android.text.Spannable)

Example 59 with Spannable

use of android.text.Spannable in project XobotOS by xamarin.

the class TextView method isCursorInsideEasyCorrectionSpan.

/**
     * @return <code>true</code> if the cursor is inside an {@link SuggestionSpan} with
     * {@link SuggestionSpan#FLAG_EASY_CORRECT} set.
     */
private boolean isCursorInsideEasyCorrectionSpan() {
    Spannable spannable = (Spannable) mText;
    SuggestionSpan[] suggestionSpans = spannable.getSpans(getSelectionStart(), getSelectionEnd(), SuggestionSpan.class);
    for (int i = 0; i < suggestionSpans.length; i++) {
        if ((suggestionSpans[i].getFlags() & SuggestionSpan.FLAG_EASY_CORRECT) != 0) {
            return true;
        }
    }
    return false;
}
Also used : SuggestionSpan(android.text.style.SuggestionSpan) Spannable(android.text.Spannable) TextPaint(android.text.TextPaint) Paint(android.graphics.Paint)

Example 60 with Spannable

use of android.text.Spannable in project XobotOS by xamarin.

the class TextView method onRestoreInstanceState.

@Override
public void onRestoreInstanceState(Parcelable state) {
    if (!(state instanceof SavedState)) {
        super.onRestoreInstanceState(state);
        return;
    }
    SavedState ss = (SavedState) state;
    super.onRestoreInstanceState(ss.getSuperState());
    // XXX restore buffer type too, as well as lots of other stuff
    if (ss.text != null) {
        setText(ss.text);
    }
    if (ss.selStart >= 0 && ss.selEnd >= 0) {
        if (mText instanceof Spannable) {
            int len = mText.length();
            if (ss.selStart > len || ss.selEnd > len) {
                String restored = "";
                if (ss.text != null) {
                    restored = "(restored) ";
                }
                Log.e(LOG_TAG, "Saved cursor position " + ss.selStart + "/" + ss.selEnd + " out of range for " + restored + "text " + mText);
            } else {
                Selection.setSelection((Spannable) mText, ss.selStart, ss.selEnd);
                if (ss.frozenWithFocus) {
                    mFrozenWithFocus = true;
                }
            }
        }
    }
    if (ss.error != null) {
        final CharSequence error = ss.error;
        // Display the error later, after the first layout pass
        post(new Runnable() {

            public void run() {
                setError(error);
            }
        });
    }
}
Also used : SpannedString(android.text.SpannedString) SpannableString(android.text.SpannableString) Spannable(android.text.Spannable) TextPaint(android.text.TextPaint) Paint(android.graphics.Paint)

Aggregations

Spannable (android.text.Spannable)333 Paint (android.graphics.Paint)122 TextPaint (android.text.TextPaint)97 SpannableString (android.text.SpannableString)72 Editable (android.text.Editable)42 InputMethodManager (android.view.inputmethod.InputMethodManager)34 Spanned (android.text.Spanned)32 SuggestionSpan (android.text.style.SuggestionSpan)29 View (android.view.View)28 SpannableStringBuilder (android.text.SpannableStringBuilder)24 ForegroundColorSpan (android.text.style.ForegroundColorSpan)21 TextView (android.widget.TextView)17 ClickableSpan (android.text.style.ClickableSpan)14 StyleSpan (android.text.style.StyleSpan)14 Intent (android.content.Intent)13 KeyEvent (android.view.KeyEvent)13 URLSpan (android.text.style.URLSpan)12 Layout (android.text.Layout)11 Parcelable (android.os.Parcelable)8 SpannedString (android.text.SpannedString)8