@Override public CharSequence filter( CharSequence src, int start, int end, Spanned dest, int dstart, int dend) { int dindex = 0; int count = 0; int attempt = 0; maxLen = maxlenChar; while (dindex < src.length()) { char c = src.charAt(dindex++); count++; if (c >= 128) { maxLen = maxLenHanzi; } } dindex = 0; while (dindex < dest.length()) { char c = dest.charAt(dindex++); count++; if (c >= 128) { maxLen = maxLenHanzi; } } attempt = count; if (count > maxLen) { // more words input than you want ,give up the redundant character count = maxLen; src = ""; } if (mCallBack != null) { mCallBack.lengthChange(count, attempt); } return src; }
@Override public CharSequence filter( CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { CharSequence filtered = super.filter(source, start, end, dest, dstart, dend); if (filtered == null) { filtered = source.subSequence(start, end); } String result = String.valueOf(dest.subSequence(0, dstart)) + filtered + dest.subSequence(dend, dest.length()); if ("".equals(result)) { return result; } int val = getSelectedPos(result); /* Ensure the user can't type in a value greater * than the max allowed. We have to allow less than min * as the user might want to delete some numbers * and then type a new number. */ if (val > mEnd) { return ""; } else { return filtered; } }
static Action newReplaceText(CharSequence text, int start, int end) { if (start < 0 || start > end) { Log.e(LOGTAG, "invalid replace text offsets: " + start + " to " + end); throw new IllegalArgumentException("invalid replace text offsets"); } int actionType = TYPE_REPLACE_TEXT; if (text instanceof Spanned) { final Spanned spanned = (Spanned) text; final Object[] spans = spanned.getSpans(0, spanned.length(), Object.class); for (Object span : spans) { if ((spanned.getSpanFlags(span) & Spanned.SPAN_COMPOSING) != 0) { actionType = TYPE_COMPOSE_TEXT; break; } } } final Action action = new Action(actionType); action.mSequence = text; action.mStart = start; action.mEnd = end; return action; }
public void setEnableScrolling(boolean enableScrolling) { if (this.strategy == null || this.strategy.isScrolling() != enableScrolling) { int pos = -1; boolean wasNull = true; Spanned text = null; if (this.strategy != null) { pos = this.strategy.getPosition(); text = this.strategy.getText(); this.strategy.clearText(); wasNull = false; } if (enableScrolling) { this.strategy = new ScrollingStrategy(this, this.getContext()); } else { this.strategy = new FixedPagesStrategy(this, configuration); } if (!wasNull) { this.strategy.setPosition(pos); } if (text != null && text.length() > 0) { this.strategy.loadText(text); } } }
public void store(View v) { Spanned s = (Spanned) mTextView.getText(); BackgroundColorSpan[] spans = s.getSpans(0, s.length(), BackgroundColorSpan.class); BufferedWriter bw = null; try { int len = spans.length; bw = new BufferedWriter(new FileWriter(mFile)); bw.write(String.valueOf(len)); bw.newLine(); for (BackgroundColorSpan span : spans) { int start = s.getSpanStart(span); int end = s.getSpanEnd(span); int color = span.getBackgroundColor(); bw.write("" + start + "," + end + "," + color); bw.newLine(); } bw.write(mText); clear(v); } catch (IOException e) { Log.e(TAG, "IO error", e); } finally { closeQuietly(bw); } }
/** See android.text.HtmlToSpannedConverter#getLast(android.text.Spanned, java.lang.Class) */ private static <T> T getLastSpan(Spanned text, Class<T> kind) { T[] spans = text.getSpans(0, text.length(), kind); if (spans.length == 0) { return null; } else { return spans[spans.length - 1]; } }
private void updateTextView(View bookView, Integer id, String value) { TextView textView = (TextView) bookView.findViewById(id); if (isBlankOrNull(value)) { textView.setVisibility(View.GONE); } else { textView.setVisibility(View.VISIBLE); Spanned markUp = Html.fromHtml(value); textView.setText(markUp.toString()); } }
/** * Assert span exists in the correct location. * * @param seq The spannable string to check. * @param start The starting index. * @param end The ending index. */ public static void assertPrefixSpan(CharSequence seq, int start, int end) { Assert.assertTrue(seq instanceof Spanned); Spanned spannable = (Spanned) seq; if (start > 0) { Assert.assertEquals(0, getNumForegroundColorSpansBetween(spannable, 0, start - 1)); } Assert.assertEquals(1, getNumForegroundColorSpansBetween(spannable, start, end)); Assert.assertEquals( 0, getNumForegroundColorSpansBetween(spannable, end + 1, spannable.length() - 1)); }
@Override public void onFinishTemporaryDetach() { super.onFinishTemporaryDetach(); if (mContainsImages && getText() instanceof Spanned) { Spanned text = (Spanned) getText(); TextInlineImageSpan[] spans = text.getSpans(0, text.length(), TextInlineImageSpan.class); for (TextInlineImageSpan span : spans) { span.onFinishTemporaryDetach(); } } }
public boolean hasLinkAt(float x, float y) { Integer offset = findOffsetForPosition(x, y); if (offset == null) { return false; } Spanned text = (Spanned) childView.getText(); ClickableSpan[] spans = text.getSpans(offset, offset, ClickableSpan.class); return spans != null && spans.length > 0; }
public ClickableSpan[] getLinkAt(float x, float y) { Integer offset = findOffsetForPosition(x, y); if (offset == null) { return null; } Spanned text = (Spanned) childView.getText(); ClickableSpan[] spans = text.getSpans(offset, offset, ClickableSpan.class); return spans; }
/** * Returns null if not boring; the width, ascent, and descent in the provided Metrics object (or a * new one if the provided one was null) if boring. */ public static Metrics isBoring(CharSequence text, TextPaint paint, Metrics metrics) { char[] temp = TextUtils.obtain(500); int len = text.length(); boolean boring = true; outer: for (int i = 0; i < len; i += 500) { int j = i + 500; if (j > len) j = len; TextUtils.getChars(text, i, j, temp, 0); int n = j - i; for (int a = 0; a < n; a++) { char c = temp[a]; if (c == '\n' || c == '\t' || c >= FIRST_RIGHT_TO_LEFT) { boring = false; break outer; } } } TextUtils.recycle(temp); if (boring && text instanceof Spanned) { Spanned sp = (Spanned) text; Object[] styles = sp.getSpans(0, text.length(), ParagraphStyle.class); if (styles.length > 0) { boring = false; } } if (boring) { Metrics fm = metrics; if (fm == null) { fm = new Metrics(); } int wid; synchronized (sTemp) { wid = (int) (FloatMath.ceil(Styled.measureText(paint, sTemp, text, 0, text.length(), fm))); } fm.width = wid; return fm; } else { return null; } }
@Override protected boolean verifyDrawable(Drawable drawable) { if (mContainsImages && getText() instanceof Spanned) { Spanned text = (Spanned) getText(); TextInlineImageSpan[] spans = text.getSpans(0, text.length(), TextInlineImageSpan.class); for (TextInlineImageSpan span : spans) { if (span.getDrawable() == drawable) { return true; } } } return super.verifyDrawable(drawable); }
@Override public void invalidateDrawable(Drawable drawable) { if (mContainsImages && getText() instanceof Spanned) { Spanned text = (Spanned) getText(); TextInlineImageSpan[] spans = text.getSpans(0, text.length(), TextInlineImageSpan.class); for (TextInlineImageSpan span : spans) { if (span.getDrawable() == drawable) { invalidate(); } } } super.invalidateDrawable(drawable); }
private static int getActive(CharSequence text, Object meta, int on, int lock) { if (!(text instanceof Spanned)) { return 0; } Spanned sp = (Spanned) text; int flag = sp.getSpanFlags(meta); if (flag == LOCKED) { return lock; } else if (flag != 0) { return on; } else { return 0; } }
/** @param bodyHtml escaped HTML (like in reddit Thing's body_html) */ private CharSequence createSpanned(String bodyHtml) { try { // get unescaped HTML bodyHtml = Html.fromHtml(bodyHtml).toString(); // fromHtml doesn't support all HTML tags. convert <code> and <pre> bodyHtml = Util.convertHtmlTags(bodyHtml); Spanned body = Html.fromHtml(bodyHtml); // remove last 2 newline character if (body.length() > 2) return body.subSequence(0, body.length() - 2); else return ""; } catch (Exception e) { if (Constants.LOGGING) Log.e(TAG, "createSpanned failed", e); return null; } }
@Override public void onBindViewHolder(ViewHolder holder, Cursor cursor) { final boolean isFavorite = cursor.getInt(cursor.getColumnIndex(QuotesTableHelper.IS_FAVORITE)) == 1; final boolean isAuthorNonNull = null != cursor.getString(cursor.getColumnIndex(QuotesTableHelper.AUTHOR)); final String link = cursor.getString(cursor.getColumnIndex(QuotesTableHelper.LINK)); holder.setLink(link); final String title = cursor.getString(cursor.getColumnIndex(QuotesTableHelper.TITLE)); final long id = cursor.getLong(cursor.getColumnIndex(QuotesTableHelper.ID)); holder.tvPubDate.setText( DateUtil.getItemPubDate( new Date(cursor.getLong(cursor.getColumnIndex(QuotesTableHelper.PUB_DATE))))); if (isFavorite) holder.ivFavorite.setImageResource(android.R.drawable.star_big_on); else holder.ivFavorite.setImageResource(android.R.drawable.star_big_off); holder.ivFavorite.setOnClickListener( v -> QuotesTableHelper.makeFavorite(getContext(), id, !isFavorite)); if (isAuthorNonNull) { holder.tvText.setVisibility(View.GONE); holder.ivComics.setVisibility(View.VISIBLE); final String url = cursor.getString(cursor.getColumnIndex(QuotesTableHelper.DESCRIPTION)); holder.setText(url, cursor.getString(cursor.getColumnIndex(QuotesTableHelper.AUTHOR))); if (mFavorite) holder.makeClick(0, false); else holder.makeClick(cursor.getLong(cursor.getColumnIndex(QuotesTableHelper.ID)), true); Picasso.with(getContext()).load(url).config(Bitmap.Config.ALPHA_8).into(holder.ivComics); holder.tvTitle.setText(cursor.getString(cursor.getColumnIndex(QuotesTableHelper.AUTHOR))); } else { holder.tvText.setVisibility(View.VISIBLE); holder.ivComics.setVisibility(View.GONE); String description = cursor.getString(cursor.getColumnIndex(QuotesTableHelper.DESCRIPTION)); if (!description.contains("\n")) { Spanned text = Html.fromHtml(description); holder.tvText.setText(highlightTextileNeeded(text.toString())); holder.setText(text.toString(), null); } else { holder.tvText.setText(highlightTextileNeeded(description)); holder.setText(description, null); } holder.tvTitle.setText(title); holder.tvTitle.setOnClickListener( v -> { Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(link)); getContext().startActivity(intent); }); } }
public void setText(String text) { Spanned spannedText = Html.fromHtml(text); text = spannedText.toString(); textWidth = (int) textPaint.measureText(text, 0, text.length()); boolean modifiedText = false; while (textWidth > maxX) { text = text.substring(0, text.length() - 1); textWidth = (int) textPaint.measureText(text, 0, text.length()); modifiedText = true; } if (modifiedText) text += "..."; this.text = text; textPaint.getTextBounds(text, 0, text.length(), bounds); }
@Test public void testTextDecorationLineLineThroughApplied() { UIManagerModule uiManager = getUIManagerModule(); ReactRootView rootView = createText( uiManager, JavaOnlyMap.of(ViewProps.TEXT_DECORATION_LINE, "line-through"), JavaOnlyMap.of(ReactTextShadowNode.PROP_TEXT, "test text")); TextView textView = (TextView) rootView.getChildAt(0); Spanned text = (Spanned) textView.getText(); UnderlineSpan[] underlineSpans = text.getSpans(0, text.length(), UnderlineSpan.class); StrikethroughSpan strikeThroughSpan = getSingleSpan(textView, StrikethroughSpan.class); assertThat(underlineSpans).hasSize(0); assertThat(strikeThroughSpan instanceof StrikethroughSpan).isTrue(); }
@TargetApi(Build.VERSION_CODES.JELLY_BEAN) public static String getImageUrl(final Context context) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) return null; final ClipboardManager cm = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); final ClipData primaryClip = cm.getPrimaryClip(); if (primaryClip.getItemCount() > 0) { final ClipData.Item item = primaryClip.getItemAt(0); final CharSequence styledText = item.coerceToStyledText(context); if (styledText instanceof Spanned) { final Spanned spanned = (Spanned) styledText; final ImageSpan[] imageSpans = spanned.getSpans(0, spanned.length(), ImageSpan.class); if (imageSpans.length == 1) return imageSpans[0].getSource(); } } return null; }
@Override public CharSequence filter( CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { if (end > 0 && dest.length() + dend - dstart + end > requiredLength) { return ""; } else { return null; } }
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 CharSequence getTextForPage(int page) { if (pageOffsets.size() < 1 || page < 0) { return null; } else if (page >= pageOffsets.size() - 1) { int startOffset = pageOffsets.get(pageOffsets.size() - 1); if (startOffset >= 0 && startOffset <= text.length() - 1) { return applySpans(this.text.subSequence(startOffset, text.length()), startOffset); } else { return applySpans(text, 0); } } else { int start = this.pageOffsets.get(page); int end = this.pageOffsets.get(page + 1); return applySpans(this.text.subSequence(start, end), start); } }
@Override public int reactTagForTouch(float touchX, float touchY) { Spanned text = (Spanned) getText(); int target = getId(); int x = (int) touchX; int y = (int) touchY; Layout layout = getLayout(); if (layout == null) { // If the layout is null, the view hasn't been properly laid out yet. Therefore, we can't find // the exact text tag that has been touched, and the correct tag to return is the default one. return target; } int line = layout.getLineForVertical(y); int lineStartX = (int) layout.getLineLeft(line); int lineEndX = (int) layout.getLineRight(line); // TODO(5966918): Consider extending touchable area for text spans by some DP constant if (x >= lineStartX && x <= lineEndX) { int index = layout.getOffsetForHorizontal(line, x); // We choose the most inner span (shortest) containing character at the given index // if no such span can be found we will send the textview's react id as a touch handler // In case when there are more than one spans with same length we choose the last one // from the spans[] array, since it correspond to the most inner react element ReactTagSpan[] spans = text.getSpans(index, index, ReactTagSpan.class); if (spans != null) { int targetSpanTextLength = text.length(); for (int i = 0; i < spans.length; i++) { int spanStart = text.getSpanStart(spans[i]); int spanEnd = text.getSpanEnd(spans[i]); if (spanEnd > index && (spanEnd - spanStart) <= targetSpanTextLength) { target = spans[i].getReactTag(); targetSpanTextLength = (spanEnd - spanStart); } } } } return target; }
@Override public CharSequence filter( CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { try { int input = Integer.parseInt(dest.toString() + source.toString()); if (isInRange(min, max, input)) return null; } catch (NumberFormatException nfe) { } return ""; }
public CharSequence filter( CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { if (mDisplayedValues == null) { return mNumberInputFilter.filter(source, start, end, dest, dstart, dend); } CharSequence filtered = String.valueOf(source.subSequence(start, end)); String result = String.valueOf(dest.subSequence(0, dstart)) + filtered + dest.subSequence(dend, dest.length()); String str = String.valueOf(result).toLowerCase(); for (String val : mDisplayedValues) { val = val.toLowerCase(); if (val.startsWith(str)) { return filtered; } } return ""; }
@Override public View getView(int position, View convertView, ViewGroup parent) { Item item = items.get(position); View view = convertView; if (view == null) { LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); view = inflater.inflate(R.layout.fragment_interview_list_item, null); } TextView title = (TextView) view.findViewById(R.id.interview_list_item_title); title.setText(item.getTitle()); Spanned descriptionText = Html.fromHtml(item.getDescription()); TextView description = (TextView) view.findViewById(R.id.interview_list_item_description); description.setText(descriptionText.subSequence(1, descriptionText.length())); return view; }
private void parseOP(final ThingInfo data, final ThingInfo contextOP) { data.setIndent(0); data.setClicked(Common.isClicked(mActivity, data.getUrl())); mActivity.runOnUiThread( new Runnable() { @Override public void run() { mActivity.mObjectStates.mCommentsList.add(0, data); if (mJumpToCommentContext > 0) { // Need to add a fake comment to get it to draw in the comments list properly, without // 'hacking' the adapter to work properly. ThingInfo tempInfo = new ThingInfo(); tempInfo.setIsContext(true); // Set the parent ID to allow the user to view the parent thread. tempInfo.setParent_id(contextOP.getParent_id()); tempInfo.setId(mJumpToCommentId); mActivity.mObjectStates.mCommentsList.add(1, tempInfo); } } }); if (data.isIs_self() && data.getSelftext_html() != null) { // HTML to Spanned String unescapedHtmlSelftext = Html.fromHtml(data.getSelftext_html()).toString(); Spanned selftext = Html.fromHtml(Util.convertHtmlTags(unescapedHtmlSelftext)); // remove last 2 newline characters if (selftext.length() > 2) data.setSpannedSelftext(selftext.subSequence(0, selftext.length() - 2)); else data.setSpannedSelftext(""); } // We might not have a title if we've intercepted a plain link to a thread. mThreadTitle = data.getTitle(); mActivity.setThreadTitle(mThreadTitle); mSubreddit = data.getSubreddit(); mThreadId = data.getId(); mOpThingInfo = data; }
/** * Extract the text from a HTML based string. This is similar to what HTML.fromHtml(...) does, but * this method also removes the embedded images instead of replacing them by a small rectangular * representation character. * * @param html * @return */ public static String extractText(CharSequence html) { String result = html.toString(); // recognize images in textview HTML contents if (html instanceof Spanned) { Spanned text = (Spanned) html; Object[] styles = text.getSpans(0, text.length(), Object.class); ArrayList<Pair<Integer, Integer>> removals = new ArrayList<Pair<Integer, Integer>>(); for (Object style : styles) { if (style instanceof ImageSpan) { int start = text.getSpanStart(style); int end = text.getSpanEnd(style); removals.add(Pair.of(start, end)); } } // sort reversed and delete image spans Collections.sort( removals, new Comparator<Pair<Integer, Integer>>() { @Override public int compare(Pair<Integer, Integer> lhs, Pair<Integer, Integer> rhs) { return rhs.getRight().compareTo(lhs.getRight()); } }); result = text.toString(); for (Pair<Integer, Integer> removal : removals) { result = result.substring(0, removal.getLeft()) + result.substring(removal.getRight()); } } // some line breaks are still in the text, source is unknown return StringUtils.replace(result, "<br />", "\n").trim(); }
@Override public CharSequence filter( CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { Log.i( "test_filter", "source = " + source + ", start = " + start + ", end = " + end + ", dest = " + dest + ", dstart = " + dstart + ", dend = " + dend); int crtLength = dest.length(); String numStr = getIntPart(source); if (crtLength == 0 || dend - dstart == crtLength) return numStr.substring(0, max > numStr.length() ? numStr.length() : max); int returnLength = max - dest.length() + dend - dstart; if (numStr.length() < returnLength) returnLength = numStr.length(); if (dest.charAt(0) == '0') { if (dstart > 0) { text.setText(numStr.substring(0, returnLength)); text.setSelection(returnLength); return ""; } if (numStr.startsWith("0")) return ""; return numStr.substring(0, returnLength); } if (numStr.startsWith("0")) { if (dstart == 0) return ""; return numStr.substring(0, returnLength); } return numStr.substring(0, returnLength); }