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);
结果就是生成半蓝半绿的文本。

你可能感兴趣的:(bean,android,String,新浪微博,null,Class)