在開發應用的過程中經常會遇到顯示一些不同的字體風格的信息,如關鍵詞高亮顯示的等。對於類似的情況,一般我們會想着使用多個TextView去實現,對於每個TextView設置不同的字體風格來滿足需求。
這里推薦的做法是使用android.text.*;和android.text.style.*;下面的組件來實現,即在一個TextView中設置不同的字體風格。主要的基本工具類有android.text.Spanned; android.text.SpannableString; android.text.SpannableStringBuilder;使用這些類來代替常規String。SpannableString和SpannableStringBuilder可以用來設置不同的Span,這些Span便是用於實現Rich Text,比如粗體,斜體,前景色,背景色,字體大小,字體風格等等,android.text.style.*中定義了很多的Span類型可供使用。下面列出一些SpannableString的屬性:

最近剛好要做一個填空題類型的考題的呈現方式,使用到這一塊,記錄下來。不多說了,效果圖先擺上,其中只有2個標識符,但無論幾個都行的,測試了很多遍。


正文:
int[] indexs = StringUtil.getRepeatIndexs(content, PARAM_FLAG); int start = 0; int end = 0; for (int i = 0; i < indexs.length; i++) { String text = mTarget.getUserPassage().split(PARAM_SPLIT)[i]; if (null == text || text.equals(" ")) { text = PARAM_FLAG; } end = indexs[i]; mTvQuestion.append(content.substring(start, end)); mTvQuestion.append(Html.fromHtml("<a href=" + end + " >" + text + "</a>")); start = end + PARAM_FLAG.length(); } mTvQuestion.append(content.substring(start));
該段代碼將識別一段文本中的所有標識符。TextView有一個append方法,然后可以不斷的向其中添加可視文本。
置於For循環以外的tv_msg.append(content.substring(count))指的是添加在最后一個標識符以后的普通文本,這是必須要加的,否則整個文本將不完整。
重要的在於mTvQuestion.append(Html.fromHtml("<a href=" + end + " >" + text + "</a>"));我們將利用這句話給標識符加下划線,利用其中的href屬性識別標識符為進行點擊做准備。
if (mIsExam) { // 通過setMovementMethod設置LinkMovementMethod類型來使LinkText有效 mTvQuestion.setMovementMethod(LinkMovementMethod.getInstance()); final CharSequence text = mTvQuestion.getText(); if (text instanceof Spannable) { int length = text.length(); Spannable sp = (Spannable) text; //獲取文本中原有的URLSpan類型的文本,保存起來 URLSpan[] urls = sp.getSpans(0, length, URLSpan.class); //使用text創建一個SpannableStringBuilder,通過clearSpans()方法清除原有的Span SpannableStringBuilder style = new SpannableStringBuilder(text); style.clearSpans(); // 重新設置text中的URLSpan for (int i = 0; i < urls.length; i++) { URLSpan url = urls[i]; final int position = i; final String value = mTarget.getUserPassage().split(PARAM_SPLIT)[i]; style.setSpan( new ClickableSpan() { private boolean isClick = false; private TextPaint ds; @Override public void updateDrawState(TextPaint ds) { if (isClick) { ds.setColor(Color.GREEN); } else { this.ds = ds; ds.setColor(Color.RED); } ds.setUnderlineText(true); } @Override public void onClick(View keyView) { isClick = true; //彈出輸入對話框 showDialog(content, position, value); updateDrawState(ds); } }, sp.getSpanStart(url), sp.getSpanEnd(url), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } mTvQuestion.setText(style); } }
該段代碼使用ClickableSpan實現點擊事件,並且實現超鏈接單擊后變色的功能。注釋寫的很清楚,相信大家都看的懂,我就不再說明了。
