private static void applySpansForTag(StartTag startTag, SpannableStringBuilder spannedText) { switch(startTag.name) { case TAG_BOLD: spannedText.setSpan(new StyleSpan(STYLE_BOLD), startTag.position, spannedText.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); return; case TAG_ITALIC: spannedText.setSpan(new StyleSpan(STYLE_ITALIC), startTag.position, spannedText.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); return; case TAG_UNDERLINE: spannedText.setSpan(new UnderlineSpan(), startTag.position, spannedText.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); return; default: break; } }
public void undo() { EditItem edit = mEditHistory.getPrevious(); if (edit == null) { return; } Editable editable = mTextView.getEditableText(); int start = edit.start; int end = start + (edit.after != null ? edit.after.length() : 0); mIsUndoOrRedo = true; editable.replace(start, end, edit.before); mIsUndoOrRedo = false; for (Object o : editable.getSpans(0, editable.length(), UnderlineSpan.class)) { editable.removeSpan(o); } Selection.setSelection(editable, edit.before == null ? start : (start + edit.before.length())); }
public void redo() { EditItem edit = mEditHistory.getNext(); if (edit == null) { return; } Editable text = mTextView.getEditableText(); int start = edit.start; int end = start + (edit.before != null ? edit.before.length() : 0); mIsUndoOrRedo = true; text.replace(start, end, edit.after); mIsUndoOrRedo = false; // This will get rid of underlines inserted when editor tries to come // up with a suggestion. for (Object o : text.getSpans(0, text.length(), UnderlineSpan.class)) { text.removeSpan(o); } Selection.setSelection(text, edit.after == null ? start : (start + edit.after.length())); }
private static void attachFontFace(SpannableStringBuilder cueText, int fontFace, int defaultFontFace, int start, int end, int spanPriority) { if (fontFace != defaultFontFace) { final int flags = Spanned.SPAN_EXCLUSIVE_EXCLUSIVE | spanPriority; boolean isBold = (fontFace & FONT_FACE_BOLD) != 0; boolean isItalic = (fontFace & FONT_FACE_ITALIC) != 0; if (isBold) { if (isItalic) { cueText.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), start, end, flags); } else { cueText.setSpan(new StyleSpan(Typeface.BOLD), start, end, flags); } } else if (isItalic) { cueText.setSpan(new StyleSpan(Typeface.ITALIC), start, end, flags); } boolean isUnderlined = (fontFace & FONT_FACE_UNDERLINE) != 0; if (isUnderlined) { cueText.setSpan(new UnderlineSpan(), start, end, flags); } if (!isUnderlined && !isBold && !isItalic) { cueText.setSpan(new StyleSpan(Typeface.NORMAL), start, end, flags); } } }
@Test public void testTextDecorationLineUnderlineApplied() { UIManagerModule uiManager = getUIManagerModule(); ReactRootView rootView = createText( uiManager, JavaOnlyMap.of(ViewProps.TEXT_DECORATION_LINE, "underline"), JavaOnlyMap.of(ReactTextShadowNode.PROP_TEXT, "test text")); TextView textView = (TextView) rootView.getChildAt(0); Spanned text = (Spanned) textView.getText(); UnderlineSpan underlineSpan = getSingleSpan(textView, UnderlineSpan.class); StrikethroughSpan[] strikeThroughSpans = text.getSpans(0, text.length(), StrikethroughSpan.class); assertThat(underlineSpan instanceof UnderlineSpan).isTrue(); assertThat(strikeThroughSpans).hasSize(0); }
@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(); }
@Test public void testTextDecorationLineUnderlineLineThroughApplied() { UIManagerModule uiManager = getUIManagerModule(); ReactRootView rootView = createText( uiManager, JavaOnlyMap.of(ViewProps.TEXT_DECORATION_LINE, "underline line-through"), JavaOnlyMap.of(ReactTextShadowNode.PROP_TEXT, "test text")); UnderlineSpan underlineSpan = getSingleSpan((TextView) rootView.getChildAt(0), UnderlineSpan.class); StrikethroughSpan strikeThroughSpan = getSingleSpan((TextView) rootView.getChildAt(0), StrikethroughSpan.class); assertThat(underlineSpan instanceof UnderlineSpan).isTrue(); assertThat(strikeThroughSpan instanceof StrikethroughSpan).isTrue(); }
public void setPenAttr(CaptionPenAttr penAttr) { mCharacterStyles.clear(); if (penAttr.italic) { mCharacterStyles.add(new StyleSpan(Typeface.ITALIC)); } if (penAttr.underline) { mCharacterStyles.add(new UnderlineSpan()); } switch (penAttr.penSize) { case CaptionPenAttr.PEN_SIZE_SMALL: mCharacterStyles.add(new RelativeSizeSpan(PROPORTION_PEN_SIZE_SMALL)); break; case CaptionPenAttr.PEN_SIZE_LARGE: mCharacterStyles.add(new RelativeSizeSpan(PROPORTION_PEN_SIZE_LARGE)); break; } switch (penAttr.penOffset) { case CaptionPenAttr.OFFSET_SUBSCRIPT: mCharacterStyles.add(new SubscriptSpan()); break; case CaptionPenAttr.OFFSET_SUPERSCRIPT: mCharacterStyles.add(new SuperscriptSpan()); break; } }
private void handleEndTag(String tag) { if (tag.equalsIgnoreCase("br")) { handleBr(mSpannableStringBuilder); } else if (tag.equalsIgnoreCase("p")) { handleP(mSpannableStringBuilder); } else if (tag.equalsIgnoreCase("b")) { end(mSpannableStringBuilder, Bold.class, new StyleSpan(Typeface.BOLD)); } else if (tag.equalsIgnoreCase("i")) { end(mSpannableStringBuilder, Italic.class, new StyleSpan(Typeface.ITALIC)); } else if (tag.equalsIgnoreCase("font")) { endFont(mSpannableStringBuilder); } else if (tag.equalsIgnoreCase("blockquote")) { handleP(mSpannableStringBuilder); end(mSpannableStringBuilder, Blockquote.class, new QuoteSpan()); } else if (tag.equalsIgnoreCase("tt")) { end(mSpannableStringBuilder, Monospace.class, new TypefaceSpan("monospace")); } else if (tag.equalsIgnoreCase("u")) { end(mSpannableStringBuilder, Underline.class, new UnderlineSpan()); } else if (mTagHandler != null) { mTagHandler.handleTag(false, tag, mSpannableStringBuilder, mReader); } }
public void clearTitle() { ssbTitle = (SpannableStringBuilder) noteTitleText.getText(); StyleSpan[] ss = ssbTitle.getSpans(noteTitleText.getSelectionStart(), noteTitleText.getSelectionEnd(), StyleSpan.class); UnderlineSpan[] us = ssbTitle.getSpans(noteTitleText.getSelectionStart(), noteTitleText.getSelectionEnd(), UnderlineSpan.class); BackgroundColorSpan[] bgSpan = ssbTitle.getSpans(noteTitleText.getSelectionStart(), noteTitleText.getSelectionEnd(), BackgroundColorSpan.class); for (int i = 0; i < bgSpan.length; i++) { ssbTitle.removeSpan(bgSpan[i]); } for (int i = 0; i < ss.length; i++) { if (ss[i].getStyle() == Typeface.BOLD_ITALIC || ss[i].getStyle() == Typeface.BOLD || ss[i].getStyle() == Typeface.ITALIC) { ssbTitle.removeSpan(ss[i]); } } for (int i = 0; i < us.length; i++) { ssbTitle.removeSpan(us[i]); } noteTitleText.setText(ssbTitle); }
public void clearContent() { ssbContent = (SpannableStringBuilder) noteContentText.getText(); StyleSpan[] ss = ssbContent.getSpans(noteContentText.getSelectionStart(), noteContentText.getSelectionEnd(), StyleSpan.class); UnderlineSpan[] us = ssbContent.getSpans(noteContentText.getSelectionStart(), noteContentText.getSelectionEnd(), UnderlineSpan.class); BackgroundColorSpan[] bgSpan = ssbContent.getSpans(noteContentText.getSelectionStart(), noteContentText.getSelectionEnd(), BackgroundColorSpan.class); for (int i = 0; i < ss.length; i++) { if (ss[i].getStyle() == Typeface.BOLD_ITALIC || ss[i].getStyle() == Typeface.BOLD || ss[i].getStyle() == Typeface.ITALIC) { ssbContent.removeSpan(ss[i]); } } for (int i = 0; i < us.length; i++) { ssbContent.removeSpan(us[i]); } for (int i = 0; i < bgSpan.length; i++) { ssbContent.removeSpan(bgSpan[i]); } noteContentText.setText(ssbContent); }
public void boldItalicText() { tags(false); if (noteContentText.hasSelection()) { ssbContent = (SpannableStringBuilder) noteContentText.getText(); ssbContent.setSpan(new UnderlineSpan(), noteContentText.getSelectionStart(), noteContentText.getSelectionEnd(), 0); ssbContent.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), noteContentText.getSelectionStart(), noteContentText.getSelectionEnd(), 0); } else if (noteTitleText.hasSelection()) { ssbTitle = (SpannableStringBuilder) noteTitleText.getText(); ssbTitle.setSpan(new UnderlineSpan(), noteTitleText.getSelectionStart(), noteTitleText.getSelectionEnd(), 0); ssbTitle.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), noteTitleText.getSelectionStart(), noteTitleText.getSelectionEnd(), 0); } }
public void testParseStrictValidClassesAndTrailingTokens() throws Exception { Spanned text = parseCueText("<v.first.loud Esme>" + "This <u.style1.style2 some stuff>is</u> text with <b.foo><i.bar>html</i></b> tags"); assertEquals("This is text with html tags", text.toString()); UnderlineSpan[] underlineSpans = getSpans(text, UnderlineSpan.class); StyleSpan[] styleSpans = getSpans(text, StyleSpan.class); assertEquals(1, underlineSpans.length); assertEquals(2, styleSpans.length); assertEquals(Typeface.ITALIC, styleSpans[0].getStyle()); assertEquals(Typeface.BOLD, styleSpans[1].getStyle()); assertEquals(5, text.getSpanStart(underlineSpans[0])); assertEquals(7, text.getSpanEnd(underlineSpans[0])); assertEquals(18, text.getSpanStart(styleSpans[0])); assertEquals(18, text.getSpanStart(styleSpans[1])); assertEquals(22, text.getSpanEnd(styleSpans[0])); assertEquals(22, text.getSpanEnd(styleSpans[1])); }
public void testParseWellFormedUnclosedEndAtCueEnd() throws Exception { Spanned text = parseCueText("An <u some trailing stuff>unclosed u tag with " + "<i>italic</i> inside"); assertEquals("An unclosed u tag with italic inside", text.toString()); UnderlineSpan[] underlineSpans = getSpans(text, UnderlineSpan.class); StyleSpan[] styleSpans = getSpans(text, StyleSpan.class); assertEquals(1, underlineSpans.length); assertEquals(1, styleSpans.length); assertEquals(Typeface.ITALIC, styleSpans[0].getStyle()); assertEquals(3, text.getSpanStart(underlineSpans[0])); assertEquals(23, text.getSpanStart(styleSpans[0])); assertEquals(29, text.getSpanEnd(styleSpans[0])); assertEquals(36, text.getSpanEnd(underlineSpans[0])); }
public void testParseWellFormedUnclosedEndAtParent() throws Exception { Spanned text = parseCueText("An unclosed u tag with <i><u>underline and italic</i> inside"); assertEquals("An unclosed u tag with underline and italic inside", text.toString()); UnderlineSpan[] underlineSpans = getSpans(text, UnderlineSpan.class); StyleSpan[] styleSpans = getSpans(text, StyleSpan.class); assertEquals(1, underlineSpans.length); assertEquals(1, styleSpans.length); assertEquals(23, text.getSpanStart(underlineSpans[0])); assertEquals(23, text.getSpanStart(styleSpans[0])); assertEquals(43, text.getSpanEnd(underlineSpans[0])); assertEquals(43, text.getSpanEnd(styleSpans[0])); assertEquals(Typeface.ITALIC, styleSpans[0].getStyle()); }
public void testParseMalformedNestedElements() throws Exception { Spanned text = parseCueText("<b><u>An unclosed u tag with <i>italic</u> inside</i></b>"); assertEquals("An unclosed u tag with italic inside", text.toString()); UnderlineSpan[] underlineSpans = getSpans(text, UnderlineSpan.class); StyleSpan[] styleSpans = getSpans(text, StyleSpan.class); assertEquals(1, underlineSpans.length); assertEquals(2, styleSpans.length); // all tags applied until matching start tag found assertEquals(0, text.getSpanStart(underlineSpans[0])); assertEquals(29, text.getSpanEnd(underlineSpans[0])); if (styleSpans[0].getStyle() == Typeface.BOLD) { assertEquals(0, text.getSpanStart(styleSpans[0])); assertEquals(23, text.getSpanStart(styleSpans[1])); assertEquals(29, text.getSpanEnd(styleSpans[1])); assertEquals(36, text.getSpanEnd(styleSpans[0])); } else { assertEquals(0, text.getSpanStart(styleSpans[1])); assertEquals(23, text.getSpanStart(styleSpans[0])); assertEquals(29, text.getSpanEnd(styleSpans[0])); assertEquals(36, text.getSpanEnd(styleSpans[1])); } }
public void testWebvttWithCssStyle() throws IOException, SubtitleDecoderException { WebvttSubtitle subtitle = getSubtitleForTestAsset(WITH_CSS_STYLES); // Test event count. assertEquals(8, subtitle.getEventTimeCount()); // Test cues. assertCue(subtitle, 0, 0, 1234000, "This is the first subtitle."); assertCue(subtitle, 2, 2345000, 3456000, "This is the second subtitle."); Spanned s1 = getUniqueSpanTextAt(subtitle, 0); Spanned s2 = getUniqueSpanTextAt(subtitle, 2345000); Spanned s3 = getUniqueSpanTextAt(subtitle, 20000000); Spanned s4 = getUniqueSpanTextAt(subtitle, 25000000); assertEquals(1, s1.getSpans(0, s1.length(), ForegroundColorSpan.class).length); assertEquals(1, s1.getSpans(0, s1.length(), BackgroundColorSpan.class).length); assertEquals(2, s2.getSpans(0, s2.length(), ForegroundColorSpan.class).length); assertEquals(1, s3.getSpans(10, s3.length(), UnderlineSpan.class).length); assertEquals(2, s4.getSpans(0, 16, BackgroundColorSpan.class).length); assertEquals(1, s4.getSpans(17, s4.length(), StyleSpan.class).length); assertEquals(Typeface.BOLD, s4.getSpans(17, s4.length(), StyleSpan.class)[0].getStyle()); }
private void underlineInvalid(int start, int end) { if (start >= end) { return; } UnderlineSpan[] spans = getEditableText().getSpans(start, end, UnderlineSpan.class); List<KnifePart> list = new ArrayList<>(); for (UnderlineSpan span : spans) { list.add(new KnifePart(getEditableText().getSpanStart(span), getEditableText().getSpanEnd(span))); getEditableText().removeSpan(span); } for (KnifePart part : list) { if (part.isValid()) { if (part.getStart() < start) { underlineValid(part.getStart(), start); } if (part.getEnd() > end) { underlineValid(end, part.getEnd()); } } } }
private boolean containUnderline(int start, int end) { if (start > end) { return false; } if (start == end) { if (start - 1 < 0 || start + 1 > getEditableText().length()) { return false; } else { UnderlineSpan[] before = getEditableText().getSpans(start - 1, start, UnderlineSpan.class); UnderlineSpan[] after = getEditableText().getSpans(start, start + 1, UnderlineSpan.class); return before.length > 0 && after.length > 0; } } else { StringBuilder builder = new StringBuilder(); for (int i = start; i < end; i++) { if (getEditableText().getSpans(i, i + 1, UnderlineSpan.class).length > 0) { builder.append(getEditableText().subSequence(i, i + 1).toString()); } } return getEditableText().subSequence(start, end).toString().equals(builder.toString()); } }
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment getActivity().setTheme(R.style.DayTheme); if (MyApplication.nightMode2()) { initNightView(R.layout.night_mode_overlay); } View view = inflater.inflate(R.layout.fragment_about, container, false); TextView tv = (TextView) view.findViewById(R.id.link); String textStr = "https://github.com/byhieg/easyweather"; tv.setAutoLinkMask(Linkify.WEB_URLS); tv.setText(textStr); Spannable s = (Spannable) tv.getText(); s.setSpan(new UnderlineSpan() { @Override public void updateDrawState(TextPaint ds) { ds.setColor(ds.linkColor); ds.setUnderlineText(false); } }, 0, textStr.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); return view; }
/** * 把内容是电话的突出出来,然后添加点击事件 * @param tv * @param context * @param contentStr * @param listener */ public static void contentToPhone(TextView tv,Context context,String contentStr,int color,final onClickSpannableListener listener){ List<PhoneEntity> phones = RexUtils.byContextGetPhone(contentStr); SpannableString ss = new SpannableString(contentStr); for (PhoneEntity phoneEntity : phones) { final String phone = phoneEntity.str; ss.setSpan(new ClickableSpan(){ //在onClick方法中可以编写单击链接时要执行的动作 @Override public void onClick(View widget){ listener.onClick(widget,phone); } },phoneEntity.start, phoneEntity.end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE); ss.setSpan(new UnderlineSpan(), phoneEntity.start, phoneEntity.end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE); //因为 ClickableSpan 会变成蓝色的 即必须在后边设置颜色 ss.setSpan(new ForegroundColorSpan(color), phoneEntity.start, phoneEntity.end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE); } tv.setText(ss); //在单击链接时凡是有要执行的动作,都必须设置MovementMethod对象 tv.setMovementMethod(LinkMovementMethod.getInstance()); }
private void applyHeader() { getActivity().runOnUiThread(new Runnable() { @Override public void run() { if(mInfo == null) { mHeader.setText(""); } else { // Make sure it's underlined so it at least LOOKS like a // thing someone might click. Graticule g = mInfo.getGraticule(); SpannableString text = new SpannableString(getString(R.string.wiki_dialog_header, DateFormat.getDateInstance(DateFormat.MEDIUM).format(mInfo.getCalendar().getTime()), (g == null ? getString(R.string.globalhash_label) : g.getLatitudeString(false) + " " + g.getLongitudeString(false)))); text.setSpan(new UnderlineSpan(), 0, text.length(), 0); mHeader.setText(text); } } }); }
private Spanned applyMarkdown(String text) { SpannableStringBuilder spannableString = new SpannableStringBuilder(text); int diff = 0; Matcher m = initialsPattern.matcher(text); while(m.find()) { String entireMatch = m.group(0); String capturedGroup = m.group(1); int start = m.start() - diff; int end = m.end() - diff; spannableString.setSpan(new StyleSpan(Typeface.BOLD), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); spannableString.setSpan(new UnderlineSpan(), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); spannableString.replace(start, end, capturedGroup.toUpperCase()); diff += entireMatch.length() - capturedGroup.length(); } return spannableString; }