Android的TextView使用Html来处理图片显示、字体样式、超链接等

一、[Android实例]实现TextView里的文字有不同颜色

转eoe:http://www.eoeandroid.com/thread-4496-1-1.html

1 import android.text.Html;
2  
3 TextView t3 = (TextView) findViewById(R.id.text3);
4         t3.setText(
5             Html.fromHtml(
6                 "<b>text3:</b>  Text with a " +
7                 "<a href=\"http://www.google.com\">link</a> " +
8                 "created in the Java source code using HTML."));

二、TextView显示html文件中的图片

转javaeye:http://da-en.javaeye.com/blog/712415

我们知道要让TextView解析和显示Html代码。可以使用

1 Spanned text = Html.fromHtml(source);
2 tv.setText(text);

来实现,这个用起来简单方便。
但是,怎样让TextView也显示Html中<image>节点的图像呢?

我们可以看到fromHtml还有另一个重构:
fromHtml(String source, Html.ImageGetter imageGetter, Html.TagHandler tagHandler)

实现一下ImageGetter就可以让图片显示了:

01 ImageGetter imgGetter = new Html.ImageGetter() {
02              @Override
03              public Drawable getDrawable(String source) {
04                    Drawable drawable = null;
05                    drawable = Drawable.createFromPath(source);  // Or fetch it from the URL
06                    // Important
07                    drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable
08                                  .getIntrinsicHeight());
09                    return drawable;
10              }
11 };

至于TagHandler,我们这里不需要使用,可以直接传null。
参考文档:
http://tech-droid.blogspot.com/2010/06/textview-with-html-content.html英语好的朋友就直接看英文文档吧。

三、Android---文字中插入表情

转载自:http://blog.163.com/spf9190@126/blog/static/50207531201091545954587/

这段时间在做一个短信项目,需要实现短信中插入表情的功能,本一位非常困难,经过一段时间的研究,发现还是比较簡単的,现在总结如下。

 以短信输入框为例,短信的输入框是一个EditText,它的append方法不仅可以加入字符串,还可以添加HTML标记。以下就是使用HTML标记添加表情的具体操作。

   首先需要构建一个ImageGetter,作用是通过HTML标记获得对应在res目录下的图片:

01 ImageGetter imageGetter = new ImageGetter() { 
02         @Override
03        public Drawable getDrawable(String source) {
04        int id = Integer.parseInt(source);
05  
06       //根据id从资源文件中获取图片对象
07        Drawable d = getResources().getDrawable(id);
08        d.setBounds(0, 0, d.getIntrinsicWidth(),d.getIntrinsicHeight());
09         return d;
10        }
11 };

然后就可以直接往EditText视图中添加

1 inputLable.append(Html.fromHtml("<img src='"+clickedImageId+"'/>", imageGetter, null));

其中 Html.fromHtml("<img src='"+clickedImageId+"'/>"就是HTML的图片标记,在Android中支持了部分HTML标记的使用(这方面我还在继续研究),HTML标记必须被Html.fromHtml修饰。imageGetter即为之前创建的ImageGetter类型的对象。

很简单的几句代码就解决了问题,不仅在EditText中,在TextView中同样可以这样插入图片。

效果图:

Android的TextView使用Html来处理图片显示、字体样式、超链接等_第1张图片

四、android 短信字符转表情显示过程
android 的短信实现方式普通用户适应的话需要长时间的使用才能习惯,将andorid的短信模式设置成我们常用的(一般人用户)的习惯。在查看字符转图片的过程中可以猜测出腾讯的QQ表情的原理应该是一样的只是在传送非常用的表情时是将 byte数据转换为 image.

以下代码摘录至android源码里面的MMS项目,其中的

package com.android.mms.ui 里的 MessageListItem.java

package com.android.mms.util 里的 SmileyParser.java

001 /***
002      *
003          * 此方法描述的是:   注意此方法在做表情转换的准备了
004          * @author:[email protected],[email protected]
005          * @version: 2010-5-13 下午03:31:13
006      */
007     private void bindCommonMessage(final MessageItem msgItem) {
008         if (mDownloadButton != null) {
009             mDownloadButton.setVisibility(View.GONE);
010             mDownloadingLabel.setVisibility(View.GONE);
011         }
012         // Since the message text should be concatenated with the sender's
013         // address(or name), I have to display it here instead of
014         // displaying it by the Presenter.
015         mBodyTextView.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
016  
017         // Get and/or lazily set the formatted message from/on the
018         // MessageItem. Because the MessageItem instances come from a
019         // cache (currently of size ~50), the hit rate on avoiding the
020         // expensive formatMessage() call is very high.
021         CharSequence formattedMessage = msgItem.getCachedFormattedMessage();
022         if (formattedMessage == null) { //肯定为null应为msgItem.formattedMessage从诞生来就没被注意过一次
023             formattedMessage = formatMessage(msgItem.mContact, msgItem.mBody,   //重点到了
024                                              msgItem.mSubject, msgItem.mTimestamp,
025                                              msgItem.mHighlight);
026             msgItem.setCachedFormattedMessage(formattedMessage);
027         }
028         mBodyTextView.setText(formattedMessage);
029  
030         if (msgItem.isSms()) {
031             hideMmsViewIfNeeded();
032         } else {
033             Presenter presenter = PresenterFactory.getPresenter(
034                     "MmsThumbnailPresenter", mContext,
035                     this, msgItem.mSlideshow);
036             presenter.present();
037  
038             if (msgItem.mAttachmentType != WorkingMessage.TEXT) {
039                 inflateMmsView();
040                 mMmsView.setVisibility(View.VISIBLE);
041                 setOnClickListener(msgItem);
042                 drawPlaybackButton(msgItem);
043             } else {
044                 hideMmsViewIfNeeded();
045             }
046         }
047  
048         drawLeftStatusIndicator(msgItem.mBoxId);
049         drawRightStatusIndicator(msgItem);
050     }
051 //------------------------------------------------------------------------------
052  
053 /***
054      *
055          * 此方法描述的是:   开始转换了哦
056          * @author:[email protected],[email protected]
057          * @version: 2010-5-13 下午03:32:52
058      */
059     private CharSequence formatMessage(String contact, String body, String subject,
060                                        String timestamp, String highlight) {
061         CharSequence template = mContext.getResources().getText(R.string.name_colon); //遇到鬼了     &lt;主题:<xliff:g id="SUBJECT">%s</xliff:g>&gt;"
062         SpannableStringBuilder buf =                   //把他当作StringBuffer只是它可以放的不是 String 而已他能放跟多类型的东西
063             new SpannableStringBuilder(TextUtils.replace(template,
064                 new String[] { "%s" },
065                 new CharSequence[] { contact })); //替换成联系人
066  
067         boolean hasSubject = !TextUtils.isEmpty(subject); //主题
068         if (hasSubject) {
069             buf.append(mContext.getResources().getString(R.string.inline_subject, subject)); //buff先在是 联系人 主题 XXXX      eg wuyi <主题:dsadasdsa> 我爱我家
070         }
071  
072         if (!TextUtils.isEmpty(body)) {
073             if (hasSubject) {
074                 buf.append(" - "); //如果内容有主题有就+ " - "    eg wuyi <主题:sdsadsadsa> -
075             }
076             SmileyParser parser = SmileyParser.getInstance(); //获得表情类了哦
077             buf.append(parser.addSmileySpans(body)); //追查 急切关注中
078         }
079         if (!TextUtils.isEmpty(timestamp)) {
080             buf.append("\n");
081             int startOffset = buf.length();
082  
083             // put a one pixel high spacer line between the message and the time stamp as requested
084             // by the spec.
085             //把之间的信息和时间戳的要求间隔一个像素的高线
086             //由规范
087             buf.append("\n");
088             buf.setSpan(new AbsoluteSizeSpan(3), startOffset, buf.length(),
089                     Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
090  
091             startOffset = buf.length();
092             buf.append(timestamp);
093             buf.setSpan(new AbsoluteSizeSpan(12), startOffset, buf.length(),
094                     Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
095             // Make the timestamp text not as dark 改变某区域颜色   时间的地方为特殊颜色
096             int color = mContext.getResources().getColor(R.color.timestamp_color);
097             buf.setSpan(new ForegroundColorSpan(color), startOffset, buf.length(),
098                     Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
099         }
100         if (highlight != null) {
101             int highlightLen = highlight.length();
102  
103             String s = buf.toString().toLowerCase();
104             int prev = 0;
105             while (true) {
106                 int index = s.indexOf(highlight, prev);
107                 if (index == -1) {
108                     break;
109                 }
110                 buf.setSpan(new StyleSpan(Typeface.BOLD), index, index + highlightLen, 0);
111                 prev = index + highlightLen;
112             }
113         }
114         return buf;
115     }
116  
117 //------------------------------------------------------------
118  
119 /**
120      * Adds ImageSpans to a CharSequence that replace textual emoticons such
121      * as :-) with a graphical version.
122      *
123      * @param text A CharSequence possibly containing emoticons
124      * @return A CharSequence annotated with ImageSpans covering any
125      *         recognized emoticons.
126      * 添加ImageSpans一个CharSequence的表情符号代替文字等     *如用图形版本:-)。
127      * 核心是把表情字符替换成ImageSpans的对象
128      */
129     public CharSequence addSmileySpans(CharSequence text) {
130         SpannableStringBuilder builder = new SpannableStringBuilder(text);
131  
132         Matcher matcher = mPattern.matcher(text);
133         while (matcher.find()) {
134             int resId = mSmileyToRes.get(matcher.group());
135             //注意下面的一块有点不好理解哦但是是核心
136             builder.setSpan(new ImageSpan(mContext, resId), matcher.start(), matcher.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
137         }
138  
139         return builder;
140     }
总结:

     android 在将字符转化为表情图像其核心代码为

builder.setSpan(new ImageSpan(mContext, resId), matcher.start(), matcher.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
原理过程是先匹配到表情字符然后通过new ImageSpan(上下文,表情地址)绘制出一个ImageView然后替换掉表情字符。


五、

Android TextView 支持的HTML标签

  • <a href="...">
  • <b>
  • <big>
  • <blockquote>
  • <br>
  • <cite>
  • <dfn>
  • <div align="...">
  • <em>
  • <font size="..." color="..." face="...">
  • <h1>
  • <h2>
  • <h3>
  • <h4>
  • <h5>
  • <h6>
  • <i>
  • <img src="...">
  • <p>
  • <small>
  • <strike>
  • <strong>
  • <sub>
  • <sup>
  • <tt>
  • <u>

原文出处:http://www.cnblogs.com/playing/archive/2011/03/17/1987033.html

你可能感兴趣的:(Android的TextView使用Html来处理图片显示、字体样式、超链接等)