public void run() { Spannable buf = mBuffer; if (buf != null) { int st = Selection.getSelectionStart(buf); int en = Selection.getSelectionEnd(buf); int start = buf.getSpanStart(TextKeyListener.ACTIVE); int end = buf.getSpanEnd(TextKeyListener.ACTIVE); if (st == start && en == end) { Selection.setSelection(buf, Selection.getSelectionEnd(buf)); } buf.removeSpan(Timeout.this); } }
public static CharSequence getHtmlText(String text) { // fixes an android bug (?): text layout fails on text with nested style tags text = removeNestedTags(text, new String[] {"i", "b", "strong"}); final Spanned htmlText = Html.fromHtml(text); if (htmlText.getSpans(0, htmlText.length(), URLSpan.class).length == 0) { return htmlText; } final Spannable newHtmlText = Spannable.Factory.getInstance().newSpannable(htmlText); for (URLSpan span : newHtmlText.getSpans(0, newHtmlText.length(), URLSpan.class)) { final int start = newHtmlText.getSpanStart(span); final int end = newHtmlText.getSpanEnd(span); final int flags = newHtmlText.getSpanFlags(span); final String url = NetworkLibrary.Instance().rewriteUrl(span.getURL(), true); newHtmlText.removeSpan(span); newHtmlText.setSpan(new URLSpan(url), start, end, flags); } return newHtmlText; }
private static void fixLinks(Spannable spannable) { for (URLSpan span : spannable.getSpans(0, spannable.length(), URLSpan.class)) { final String url = span.getURL(); int start = spannable.getSpanStart(span); int end = spannable.getSpanEnd(span); int flags = spannable.getSpanFlags(span); URLSpan newSpan = new URLSpan(url) { @Override public void updateDrawState(TextPaint paramTextPaint) { super.updateDrawState(paramTextPaint); paramTextPaint.setUnderlineText(false); paramTextPaint.setColor(0xff006FC8); } }; spannable.removeSpan(span); spannable.setSpan(newSpan, start, end, flags); } }
/** Resets all meta state to inactive. */ public static void resetMetaState(Spannable text) { text.removeSpan(CAP); text.removeSpan(ALT); text.removeSpan(SYM); text.removeSpan(SELECTING); }
/** * Stop selecting text. This does not actually collapse the selection; call {@link * android.text.Selection#setSelection} too. * * @hide pending API review */ public static void stopSelecting(View view, Spannable content) { content.removeSpan(SELECTING); }
private static void resetLock(Spannable content, Object what) { int current = content.getSpanFlags(what); if (current == LOCKED) content.removeSpan(what); }
private static void adjust(Spannable content, Object what) { int current = content.getSpanFlags(what); if (current == PRESSED) content.setSpan(what, 0, 0, USED); else if (current == RELEASED) content.removeSpan(what); }
/** * Make a layout for the transformed text (password transformation being the primary example of a * transformation) that will be updated as the base text is changed. If ellipsize is non-null, the * Layout will ellipsize the text down to ellipsizedWidth. * *@hide */ public DynamicLayout( CharSequence base, CharSequence display, TextPaint paint, int width, Alignment align, TextDirectionHeuristic textDir, float spacingmult, float spacingadd, boolean includepad, TextUtils.TruncateAt ellipsize, int ellipsizedWidth) { super( (ellipsize == null) ? display : (display instanceof Spanned) ? new SpannedEllipsizer(display) : new Ellipsizer(display), paint, width, align, textDir, spacingmult, spacingadd); mBase = base; mDisplay = display; if (ellipsize != null) { mInts = new PackedIntVector(COLUMNS_ELLIPSIZE); mEllipsizedWidth = ellipsizedWidth; mEllipsizeAt = ellipsize; } else { mInts = new PackedIntVector(COLUMNS_NORMAL); mEllipsizedWidth = width; mEllipsizeAt = null; } mObjects = new PackedObjectVector<Directions>(1); mIncludePad = includepad; /* * This is annoying, but we can't refer to the layout until * superclass construction is finished, and the superclass * constructor wants the reference to the display text. * * This will break if the superclass constructor ever actually * cares about the content instead of just holding the reference. */ if (ellipsize != null) { Ellipsizer e = (Ellipsizer) getText(); e.mLayout = this; e.mWidth = ellipsizedWidth; e.mMethod = ellipsize; mEllipsize = true; } // Initial state is a single line with 0 characters (0 to 0), // with top at 0 and bottom at whatever is natural, and // undefined ellipsis. int[] start; if (ellipsize != null) { start = new int[COLUMNS_ELLIPSIZE]; start[ELLIPSIS_START] = ELLIPSIS_UNDEFINED; } else { start = new int[COLUMNS_NORMAL]; } Directions[] dirs = new Directions[] {DIRS_ALL_LEFT_TO_RIGHT}; Paint.FontMetricsInt fm = paint.getFontMetricsInt(); int asc = fm.ascent; int desc = fm.descent; start[DIR] = DIR_LEFT_TO_RIGHT << DIR_SHIFT; start[TOP] = 0; start[DESCENT] = desc; mInts.insertAt(0, start); start[TOP] = desc - asc; mInts.insertAt(1, start); mObjects.insertAt(0, dirs); // Update from 0 characters to whatever the real text is reflow(base, 0, 0, base.length()); if (base instanceof Spannable) { if (mWatcher == null) mWatcher = new ChangeWatcher(this); // Strip out any watchers for other DynamicLayouts. Spannable sp = (Spannable) base; ChangeWatcher[] spans = sp.getSpans(0, sp.length(), ChangeWatcher.class); for (int i = 0; i < spans.length; i++) sp.removeSpan(spans[i]); sp.setSpan( mWatcher, 0, base.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE | (PRIORITY << Spannable.SPAN_PRIORITY_SHIFT)); } }
private void reflow(CharSequence s, int where, int before, int after) { DynamicLayout ml = mLayout.get(); if (ml != null) ml.reflow(s, where, before, after); else if (s instanceof Spannable) ((Spannable) s).removeSpan(this); }
public void onSpanChanged(Spannable buf, Object what, int s, int e, int start, int stop) { if (what == Selection.SELECTION_END) { buf.removeSpan(TextKeyListener.ACTIVE); removeTimeouts(buf); } }
private static void removeTimeouts(Spannable buf) { Timeout[] timeout = buf.getSpans(0, buf.length(), Timeout.class); for (int i = 0; i < timeout.length; i++) { Timeout t = timeout[i]; t.removeCallbacks(t); t.mBuffer = null; buf.removeSpan(t); } }