TextView中分段改變文字的樣式

接觸android不深的童鞋們是不是以爲TextView只能整體設置顏色,大小啊?我最開始就是這麼認爲的。但是看到新浪微博客戶端的效果時發現,這裏有得搞。仔細看看android.text包,你會很有收穫。這裏不單可以分段改變TextView中的文字的樣式,還可以向裏面插入圖片!有意思吧。android.text的包結構看起來豐滿吧,這裏主要用到Spanable和Span兩部分(這哥倆都是接口,從命名方式也能看得出來)。Spanable說明實現類的樣式可以被改變,Span說明實現類可以去改變別的類的樣式。

下面寫了一個用於改變文本樣式的工具類,看我都用了小半年了,還是很管用的。

/**
 * 目的:用list給一個view設置不同的樣式<br />
 * 包括:1. 字體的顏色和大小,2. 點擊效果
 * 
 * @author Daniel
 * @version 創建時間:2012-3-16 下午3:43:17
 */
public class TextParser {
	private List<TextBean> textList;

	public TextParser() {
		textList = new LinkedList<TextBean>();
	}

	/**
	 * 添加文字
	 * */
	public TextParser append(String text, int size, int color) {
		if (text == null) {
			return this;
		}
		TextBean bean = new TextBean();
		bean.text = text;
		bean.size = size;
		bean.color = color;
		textList.add(bean);

		return this;
	}

	/**
	 * 添加帶鏈接的文字
	 * */
	public TextParser append(String text, int size, int color,
			OnClickListener onClickListener) {
		if (text == null) {
			return this;
		}
		TextBean bean = new TextBean();
		bean.text = text;
		bean.size = size;
		bean.color = color;
		bean.onClickListener = onClickListener;
		textList.add(bean);

		return this;
	}

	/**
	 * 寫入TextView
	 * */
	public void parse(TextView textView) {
		// 先將文字放在一起,傳入到SpannableBuilder中
		// 後面做的是對文本進行修飾和替換
		StringBuilder sBuilder = new StringBuilder();
		for (TextBean bean : textList) {
			sBuilder.append(bean.text);
		}

		// 所有的文字和效果都要寫在Spannable中,SpanableStringBuilder用於創建Spannable,
		// 其實它也是Spannable的一個實現類
		SpannableStringBuilder style = new SpannableStringBuilder(sBuilder);
		int position = 0;
		for (TextBean bean : textList) {
			if (bean.onClickListener != null) {
				// 如果有點擊,則在上面添加點擊處理的Span
				style.setSpan(new MyClickableSpan(bean.onClickListener),// Span接口用於實現對文本的修飾的具體內容
						position,// 修飾的起始位置
						position + bean.text.length(),// 修飾的結束位置
						Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
			}
			// 字體上色,字體的背景顏色也可以單獨改變
			style.setSpan(new ForegroundColorSpan(bean.color), position,
					position + bean.text.length(),
					Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
			// 改變字體大小
			style.setSpan(new AbsoluteSizeSpan(bean.size), position, position
					+ bean.text.length(), Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
			/*
			 * 如上所示,Spannalbe接口是說這個類可以被改變,Span說的是這個類可以去改變別的類
			 * 整個改變樣式做的就是用Span去改變Spannable中的內容。
			 */
			position += bean.text.length();
		}

		// 設置TextView讓文字可以被點擊
		textView.setMovementMethod(LinkMovementMethod.getInstance());
		textView.setText(style);
	}

	/**
	 * 用於記錄文本的內容,字體,大小和監聽器
	 * */
	private class TextBean {
		public OnClickListener onClickListener;
		public String text;
		public int size;
		public int color;
	}

	/**
	 * 用於更改文字點擊的事件和效果
	 * */
	private static class MyClickableSpan extends ClickableSpan {
		private OnClickListener mOnClickListener;

		public MyClickableSpan(OnClickListener onClickListener) {
			mOnClickListener = onClickListener;
		}

		@Override
		public void onClick(View widget) {
			if (mOnClickListener != null) {
				mOnClickListener.onClick(widget);
			}
		}

		@Override
		public void updateDrawState(TextPaint ds) {
		}

	}

}

使用這個類改變文本樣式共分三布:

  1. 創建TextParser類
  2. 通過append向TextParser中添加文本和樣式參數
  3. 調用parse將結果輸出到TextView中
簡單吧。以下是例子
TextView textView=new TextView(context);
TextParser textParser=new TextParser();
textParser.append("A text in one style, ", 20, Color.BLUE);
textParser.append("and a text in another style.", 10, Color.GREEN);
textParser.parse(textView);
結果就是生成半藍半綠的文本。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章