`
xixinfei
  • 浏览: 414560 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

用TextView实现Rich Text---在同一个TextView中设置不同的字体风格

阅读更多

http://blog.csdn.net/hitlion2008/article/details/6856780

背景介绍

在开发应用过程中经常会遇到显示一些不同的字体风格的信息犹如默认的LockScreen上面的时间和充电信息。对于类似的情况,可能第一反应就是用不同的多个TextView来实现,对于每个TextView设置不同的字体风格以满足需求。

这里推荐的做法是使用android.text.*;和 android.text.style.*;下面的组件来实现RichText:也即在同一个TextView中设置不同的字体风格。对于某些应用,比如 文本编辑,记事本,彩信,短信等地方,还必须使用这些组件才能达到想到的显示效果。

主要的基本工具类有android.text.Spanned; android.text.SpannableString; android.text.SpannableStringBuilder;使用这些类来代替常规String。SpannableString和 SpannableStringBuilder可以用来设置不同的Span,这些Span便是用于实现Rich Text,比如粗体,斜体,前景色,背景色,字体大小,字体风格等等,android.text.style.*中定义了很多的Span类型可供使用。

这是相关的API的Class General Hierarchy:

因为Spannable等最终都实现了CharSequence接口,所以可以直接把SpannableString和SpannableStringBuilder通过TextView.setText()设置给TextView。

使用方法

当要显示Rich Text信息的时候,可以使用创建一个SpannableString或SpannableStringBuilder,它们的区别在于 SpannableString像一个String一样,构造对象的时候传入一个String,之后再无法更改String的内容,也无法拼接多个 SpannableString;而SpannableStringBuilder则更像是StringBuilder,它可以通过其append()方 法来拼接多个String:

  1. SpannableString word = new SpannableString("The quick fox jumps over the lazy dog");  
  2.   
  3. SpannableStringBuilder multiWord = new SpannableStringBuilder();  
  4. multiWord.append("The Quick Fox");  
  5. multiWord.append("jumps over");  
  6. multiWord.append("the lazy dog");  

创建完Spannable对象后,就可以为它们设置Span来实现想要的Rich Text了,常见的Span有:

  • AbsoluteSizeSpan(int size) ---- 设置字体大小,参数是绝对数值,相当于Word中的字体大小
  • RelativeSizeSpan(float proportion) ---- 设置字体大小,参数是相对于默认字体大小的倍数,比如默认字体大小是x, 那么设置后的字体大小就是x*proportion,这个用起来比较灵活,proportion>1就是放大(zoom in), proportion<1就是缩小(zoom out)
  • ScaleXSpan(float proportion) ---- 缩放字体,与上面的类似,默认为1,设置后就是原来的乘以proportion,大于1时放大(zoon in),小于时缩小(zoom out)
  • BackgroundColorSpan(int color) ----背景着色,参数是颜色数值,可以直接使用android.graphics.Color里面定义的常量,或是用Color.rgb(int, int, int)
  • ForegroundColorSpan(int color) ----前景着色,也就是字的着色,参数与背景着色一致
  • TypefaceSpan(String family) ----字体,参数是字体的名字比如“sans", "sans-serif"等
  • StyleSpan(Typeface style) -----字体风格,比如粗体,斜体,参数是android.graphics.Typeface里面定义的常量,如Typeface.BOLD,Typeface.ITALIC等等。
  • StrikethroughSpan----如果设置了此风格,会有一条线从中间穿过所有的字,就像被划掉一样

对于这些Sytle span在使用的时候通常只传上面所说明的构造参数即可,不需要设置其他的属性,如果需要的话,也可以对它们设置其他的属性,详情可以参见文档
SpannableString和SpannableStringBuilder都有一个设置上述Span的方法:

  1. /** 
  2.  * Set the style span to Spannable, such as SpannableString or SpannableStringBuilder 
  3.  * @param what --- the style span, such as StyleSpan 
  4.  * @param start --- the starting index of characters to which the style span to apply 
  5.  * @param end --- the ending index of characters to which the style span to apply 
  6.  * @param flags --- the flag specified to control 
  7.  */  
  8. setSpan(Object what, int start, int end, int flags);  

其中参数what是要设置的Style span,start和end则是标识String中Span的起始位置,而 flags是用于控制行为的,通常设置为0或Spanned中定义的常量,常用的有:

  • Spanned.SPAN_EXCLUSIVE_EXCLUSIVE --- 不包含两端start和end所在的端点
  • Spanned.SPAN_EXCLUSIVE_INCLUSIVE --- 不包含端start,但包含end所在的端点
  • Spanned.SPAN_INCLUSIVE_EXCLUSIVE --- 包含两端start,但不包含end所在的端点
  • Spanned.SPAN_INCLUSIVE_INCLUSIVE--- 包含两端start和end所在的端点

这里理解起来就好像数学中定义区间,开区间还是闭区间一样的。还有许多其他的Flag,可以参考这里。这里要重点说明下关于参数0,有很多时候,如果设置了上述的参数,那么Span会从start应用到Text结尾,而不是在start和end二者之间,这个时候就需要使用Flag 0。

Linkify

 

另外,也可以对通过TextView.setAutoLink(int)设置其Linkify属性,其用处在于,TextView会自动检查其内容,会识别出phone number, web address or email address,并标识为超链接,可点击,点击后便跳转到相应的应用,如Dialer,Browser或Email。Linkify有几个常用选项,更多的请参考文档

  • Linkify.EMAIL_ADDRESS -- 仅识别出TextView中的Email在址,标识为超链接,点击后会跳到Email,发送邮件给此地址
  • Linkify.PHONE_NUMBERS -- 仅识别出TextView中的电话号码,标识为超链接,点击后会跳到Dialer,Call这个号码
  • Linkify.WEB_URLS-- 仅识别出TextView中的网址,标识为超链接,点击后会跳到Browser打开此URL
  • Linkify.ALL -- 这个选项是识别出所有系统所支持的特殊Uri,然后做相应的操作

权衡选择

个 人认为软件开发中最常见的问题不是某个技巧怎么使用的问题,而是何时该使用何技巧的问题,因为实现同一个目标可能有N种不同的方法,就要权衡利弊,选择最 合适的一个,正如常言所云,没有最好的,只有最适合的。如前面所讨论的,要想用不同的字体展现不同的信息可能的解法,除了用Style Span外还可以用多个TextView。那么就需要总结下什么时候该使用StyleSpan,什么时候该使用多个TextView:

  1. 如果显示的是多个不同类别的信息,就应该使用多个TextView,这样也方便控制和改变各自的信息,例子就是默认LockScreen上面的日期和充电信息,因为它们所承载不同的信息,所以应该使用多个TextView来分别呈现。
  2. 如果显示的是同一类信息,或者同一个信息,那么应该使用StyleSpan。比如,短信息中,要把联系人的相关信息突出显示;或是想要Highlight某些信息等。
  3. 如果要实现Rich text,没办法,只能使用Style span。
  4. 如果要实现某些特效,也可以考虑使用StyleSpan。设置不同的字体风格只是Style span的初级应用,如果深入研究,可以发现很多奇妙的功效。

实例

 

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout  
  3.   xmlns:android="http://schemas.android.com/apk/res/android"  
  4.   android:layout_width="wrap_content"  
  5.   android:layout_height="wrap_content"  
  6.   android:orientation="vertical">  
  7.   <ScrollView  
  8.     android:layout_width="fill_parent"  
  9.     android:layout_height="wrap_content">  
  10.         <LinearLayout  
  11.             android:layout_width="fill_parent"  
  12.             android:layout_height="wrap_content"  
  13.             android:orientation="vertical">  
  14.               <TextView  
  15.                 android:id="@+id/text_view_font_1"  
  16.                 android:layout_width="fill_parent"  
  17.                 android:layout_height="wrap_content"  
  18.                 />  
  19.               <TextView  
  20.                 android:id="@+id/text_view_font_2"  
  21.                 android:layout_width="fill_parent"  
  22.                 android:layout_height="wrap_content"  
  23.                 />  
  24.               <TextView  
  25.                 android:id="@+id/text_view_font_3"  
  26.                 android:layout_width="fill_parent"  
  27.                 android:layout_height="wrap_content"  
  28.                 />  
  29.               <TextView  
  30.                 android:id="@+id/text_view_font_4"  
  31.                 android:layout_width="fill_parent"  
  32.                 android:layout_height="wrap_content"  
  33.                 />  
  34.               <TextView  
  35.                 android:id="@+id/text_view_font_5"  
  36.                 android:layout_width="fill_parent"  
  37.                 android:layout_height="wrap_content"  
  38.                 />  
  39.        </LinearLayout>  
  40.     </ScrollView>  
  41. </LinearLayout>  

Source code:

  1. package com.android.effective;  
  2.   
  3.   
  4.   
  5. import java.util.regex.Matcher;  
  6.   
  7. import java.util.regex.Pattern;  
  8.   
  9.   
  10.   
  11. import android.app.Activity;  
  12.   
  13. import android.graphics.Color;  
  14.   
  15. import android.graphics.Typeface;  
  16.   
  17. import android.os.Bundle;  
  18.   
  19. import android.text.Spannable;  
  20.   
  21. import android.text.SpannableString;  
  22.   
  23. import android.text.SpannableStringBuilder;  
  24.   
  25. import android.text.style.AbsoluteSizeSpan;  
  26.   
  27. import android.text.style.BackgroundColorSpan;  
  28.   
  29. import android.text.style.ForegroundColorSpan;  
  30.   
  31. import android.text.style.QuoteSpan;  
  32.   
  33. import android.text.style.RelativeSizeSpan;  
  34.   
  35. import android.text.style.ScaleXSpan;  
  36.   
  37. import android.text.style.StrikethroughSpan;  
  38.   
  39. import android.text.style.StyleSpan;  
  40.   
  41. import android.text.style.TypefaceSpan;  
  42.   
  43. import android.text.style.URLSpan;  
  44.   
  45. import android.text.util.Linkify;  
  46.   
  47. import android.widget.TextView;  
  48.   
  49.   
  50.   
  51. public class TextViewFontActivity extends Activity {  
  52.   
  53.     @Override  
  54.   
  55.     public void onCreate(Bundle bundle) {  
  56.   
  57.         super.onCreate(bundle);  
  58.   
  59.         setContentView(R.layout.textview_font_1);  
  60.   
  61.           
  62.   
  63.         // Demonstration of basic SpannableString and spans usage  
  64.   
  65.         final TextView textWithString = (TextView) findViewById(R.id.text_view_font_1);  
  66.   
  67.         String w = "The quick fox jumps over the lazy dog";  
  68.   
  69.         int start = w.indexOf('q');  
  70.   
  71.         int end = w.indexOf('k') + 1;  
  72.   
  73.         Spannable word = new SpannableString(w);  
  74.   
  75.         word.setSpan(new AbsoluteSizeSpan(22), start, end,   
  76.   
  77.                 Spannable.SPAN_INCLUSIVE_INCLUSIVE);  
  78.   
  79.         word.setSpan(new StyleSpan(Typeface.BOLD), start, end,   
  80.   
  81.                 Spannable.SPAN_INCLUSIVE_INCLUSIVE);  
  82.   
  83.         word.setSpan(new BackgroundColorSpan(Color.RED), start, end,   
  84.   
  85.                 Spannable.SPAN_INCLUSIVE_INCLUSIVE);  
  86.   
  87.         textWithString.setText(word);  
  88.   
  89.           
  90.   
  91.         // Demonstration of basic SpannableStringBuilder and spans usage  
  92.   
  93.         final TextView textWithBuilder = (TextView) findViewById(R.id.text_view_font_2);  
  94.   
  95.         SpannableStringBuilder word2 = new SpannableStringBuilder();  
  96.   
  97.         final String one = "Freedom is nothing but a chance to be better!";  
  98.   
  99.         final String two = "The quick fox jumps over the lazy dog!";  
  100.   
  101.         final String three = "The tree of liberty must be refreshed from time to time with " +  
  102.   
  103.                 "the blood of patroits and tyrants!";  
  104.   
  105.         word2.append(one);  
  106.   
  107.         start = 0;  
  108.   
  109.         end = one.length();  
  110.   
  111.         word2.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
  112.   
  113.   
  114.   
  115.         word2.append(two);  
  116.   
  117.         start = end;  
  118.   
  119.         end += two.length();  
  120.   
  121.         word2.setSpan(new ForegroundColorSpan(Color.CYAN), start, end,   
  122.   
  123.                 Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
  124.   
  125.         word2.append(three);  
  126.   
  127.         start = end;  
  128.   
  129.         end += three.length();  
  130.   
  131.         word2.setSpan(new URLSpan(three), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
  132.   
  133.         textWithBuilder.setText(word2);  
  134.   
  135.           
  136.   
  137.         // Troubleshooting when using SpannableStringBuilder  
  138.   
  139.         final TextView textTroubles = (TextView) findViewById(R.id.text_view_font_3);  
  140.   
  141.         SpannableStringBuilder word3 = new SpannableStringBuilder();  
  142.   
  143.         start = 0;  
  144.   
  145.         end = one.length();  
  146.   
  147.         // Caution: must first append or set text to SpannableStringBuilder or SpannableString  
  148.   
  149.         // then set the spans to them, otherwise, IndexOutOfBoundException is thrown when setting spans  
  150.   
  151.         word3.append(one);  
  152.   
  153.         // For AbsoluteSizeSpan, the flag must be set to 0, otherwise, it will apply this span to until end of text  
  154.   
  155.         word3.setSpan(new AbsoluteSizeSpan(22), start, end, 0);//Spannable.SPAN_INCLUSIVE_INCLUSIVE);  
  156.   
  157.         // For BackgroundColorSpanSpan, the flag must be set to 0, otherwise, it will apply this span to end of text  
  158.   
  159.         word3.setSpan(new BackgroundColorSpan(Color.DKGRAY), start, end, 0); //Spannable.SPAN_INCLUSIVE_INCLUSIVE);  
  160.   
  161.         word3.append(two);  
  162.   
  163.         start = end;  
  164.   
  165.         end += two.length();  
  166.   
  167.         word3.setSpan(new TypefaceSpan("sans-serif"), start, end,   
  168.   
  169.                 Spannable.SPAN_INCLUSIVE_INCLUSIVE);  
  170.   
  171.         // TODO: sometimes, flag must be set to 0, otherwise it will apply the span to until end of text  
  172.   
  173.         // which MIGHT has nothing to do with specific span type.  
  174.   
  175.         word3.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), start, end, 0);//Spannable.SPAN_INCLUSIVE_INCLUSIVE);  
  176.   
  177.         word3.setSpan(new ScaleXSpan(0.618f), start, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE);  
  178.   
  179.         word3.setSpan(new StrikethroughSpan(), start, end, 0);//Spannable.SPAN_INCLUSIVE_INCLUSIVE);  
  180.   
  181.         word3.setSpan(new ForegroundColorSpan(Color.CYAN), start, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE);  
  182.   
  183.         word3.setSpan(new QuoteSpan(), start, end, 0); //Spannable.SPAN_INCLUSIVE_INCLUSIVE);  
  184.   
  185.         word3.append(three);  
  186.   
  187.         start = end;  
  188.   
  189.         end += three.length();  
  190.   
  191.         word3.setSpan(new RelativeSizeSpan((float) Math.E), start, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE);  
  192.   
  193.         word3.setSpan(new ForegroundColorSpan(Color.BLUE), start, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE);  
  194.   
  195.         textTroubles.setText(word3);  
  196.   
  197.           
  198.   
  199.         // Highlight some patterns  
  200.   
  201.         final String four = "The gap between the best software engineering " +  
  202.   
  203.                 "practice and the average practice is very wide¡ªperhaps wider " +  
  204.   
  205.                 " than in any other engineering discipline. A tool that disseminates " +  
  206.   
  207.                 "good practice would be important.¡ªFred Brooks";  
  208.   
  209.         final Pattern highlight = Pattern.compile("the");  
  210.   
  211.         final TextView textHighlight = (TextView) findViewById(R.id.text_view_font_4);  
  212.   
  213.         SpannableString word4 = new SpannableString(four);  
  214.   
  215.         Matcher m = highlight.matcher(word4.toString());  
  216.   
  217.         while (m.find()) {  
  218.   
  219.             word4.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), m.start(), m.end(),   
  220.   
  221.                     Spannable.SPAN_INCLUSIVE_INCLUSIVE);  
  222.   
  223.             word4.setSpan(new ForegroundColorSpan(Color.RED), m.start(), m.end(),   
  224.   
  225.                     Spannable.SPAN_INCLUSIVE_INCLUSIVE);  
  226.   
  227.             word4.setSpan(new StrikethroughSpan(), m.start(), m.end(),   
  228.   
  229.                     Spannable.SPAN_INCLUSIVE_INCLUSIVE);  
  230.   
  231.         }  
  232.   
  233.         textHighlight.setText(word4);  
  234.   
  235.           
  236.   
  237.         // Set numbers, URLs and E-mail address to be clickable with TextView#setAutoLinkMask  
  238.   
  239.         final TextView textClickable = (TextView) findViewById(R.id.text_view_font_5);    
  240.   
  241.         final String contact = "Email: mvp@microsoft.com\n" +  
  242.   
  243.                 "Phone: +47-24885883\n" +  
  244.   
  245.                 "Fax: +47-24885883\n" +  
  246.   
  247.                 "HTTP: www.microsoft.com/mvp.asp";  
  248.   
  249.         // Set the attribute first, then set the text. Otherwise, it won't work  
  250.   
  251.         textClickable.setAutoLinkMask(Linkify.ALL); // or set 'android:autoLink' in layout xml  
  252.   
  253.         textClickable.setText(contact);  
  254.     }  
  255. }  

The results:

分享到:
评论

相关推荐

    Android-TextView-富文本-html图片显示.rar

    在Android开发中,`TextView` 是一个非常基础且重要的组件,通常用于展示纯文本内容。然而,当开发者需要在文本中插入图片或者实现更复杂的格式时,`TextView` 的功能就显得有些不足。针对这种情况,Android 提供了...

    Android长按TextView复制文本内容,可以直接使用

    Android系统提供了一个方便的功能,允许用户通过长按`TextView`来实现文本复制,而无需额外的复杂设置。本文将详细介绍如何实现这一功能,以及相关的知识点。 首先,`TextView`默认支持长按事件,当用户在`TextView...

    ios-textview 富文本.zip

    但在实际应用中,我们经常需要更丰富的文本样式,例如添加链接、图片、列表、不同颜色和大小的文本块等,这就需要用到富文本(Rich Text)。富文本可以通过`NSAttributedString` 和 `NSMutableAttributedString` 类...

    这是一个TextView 富文本示例

    富文本(Rich Text)是指在文本中包含多种格式的文本,如字体、颜色、大小、链接、图片等,使得文本展示更加丰富多样。在Android中,我们可以通过对TextView进行特定的配置和使用特定的库来实现富文本显示。 1. **...

    可以显示富文本的TextView.zip

    使用这个自定义的TextView时,开发者需要在布局XML文件中引入,然后在代码中通过`text`方法设置HTML文本,或者在Java/Kotlin类中直接创建实例并设置。同时,确保处理好相关的生命周期问题,如在Activity或Fragment...

    TextView Html.fromHtml ScrollView——可追加自动显示最后行

    上述代码展示了如何将富文本内容设置到TextView,并使用ScrollView实现自动滚动到最后一行的功能。 综上所述,通过`Html.fromHtml`与ScrollView的组合,开发者可以轻松地在Android应用中创建一个支持富文本并能...

    小程序源码 textView.zip

    在IT行业中,小程序是一种轻量级的应用形式,它无需下载安装即可使用,为用户提供了便捷的体验。"小程序源码 textView.zip" 提供的是一个关于小程序中TextView组件的源代码包,TextView是显示文本的重要控件,广泛...

    Android-FlexibleRichTextView可以显示LaTeX图片代码的TextView

    `Android-FlexibleRichTextView`是一个专门为此目的设计的库,它使得在Android的TextView中嵌入LaTeX图像、图片以及代码变得更加灵活和便捷。 `FlexibleRichTextView`的核心特性在于其支持自定义标签,这意味着...

    新版Android开发教程.rar

    也有分析认为,谷歌并不想做一个简单的手机终端制造商或者软件平台开发商,而意在一统传统互联网和 移 动互联网。----------------------------------- Android 编程基础 4 Android Android Android Android 手机新...

    小程序源码 TextViewSample.zip

    在`.wxss`文件中,我们可以设置TextView的样式,如字体大小、颜色、行高、对齐方式等。例如: ```css text { font-size: 16px; color: #333; line-height: 24px; text-align: center; } ``` 还可以使用`...

    XRichText android 富文本的实现

    在Android开发中,富文本(Rich Text)的处理是一项重要的技术,它允许开发者展示具有多种格式的文本,如加粗、斜体、下划线、颜色、字体大小、链接、图片等。`XRichText` 是一个专为Android平台设计的富文本库,...

    ios-富文本的点击事件.zip

    在iOS开发中,富文本(Rich Text)是一种可以同时包含文字、图片、链接等多种元素的文本格式,常用于实现复杂的文本展示和交互效果。在这个"ios-富文本的点击事件.zip"压缩包中,我们看到的是一个关于如何为富文本...

    swift-一行代码搞定常见的富文本显示

    在Swift编程中,富文本(Rich Text)的处理是一个重要的环节,它允许我们在应用程序中创建具有多样格式的文本,如不同颜色、字体、大小、下划线等。本主题将聚焦于如何用一行代码轻松地实现Swift中的富文本显示。 ...

    RichText:android 自定义视图支持在 TextView 或 EditText 内显示图像

    在Android开发中,有时我们需要在TextView或EditText中不仅显示纯文本,还需要插入图像,实现类似微信、QQ等应用中的富文本功能。为了达到这个目的,Android原生的TextView和EditText并不直接支持,但可以通过自定义...

    RichText:android textview的富文本

    特征 超链接点击事件(带有按下的文本和背景颜色) 单击事件(带有按下的文本和背景颜色) 文字背景色 文字前景色 字体大小 文本样式(粗体、斜体) 文字字体 图像当然,您可以使用 api addTypeSpan添加自定义字体...

    安卓富文本编辑器

    在Android开发中,富文本编辑器(Rich Text Editor)是一个重要的组件,允许用户输入并编辑包含格式化的文本,如加粗、斜体、颜色、链接等。本项目名为"安卓富文本编辑器",旨在提供一个功能强大的解决方案,用于在...

    Android源码——卡拉OK,歌词同步程序.7z

    这通常通过LRC(Lyrics Rich Text)格式的歌词文件实现,LRC文件中包含了每个歌词段落对应的时间信息。解析LRC文件是开发歌词同步的第一步,需要读取并理解这些时间戳,以便在正确的时间显示正确的歌词。 其次,...

    SpEditTool:一个高效且可扩展的库,用于在混合图文本TextViewEditText上输入和显示gif或@mention

    `SpEditTool`是一个专为Android平台设计的高效且可扩展的库,旨在帮助开发者在混合图文本的`TextView`、`EditText`元素中轻松实现GIF动态图和`@mention`功能。这个库极大地简化了在文本中插入和展示动态内容以及处理...

Global site tag (gtag.js) - Google Analytics