这几天在仿写新浪微博客户端,在处理微博信息的时候需要处理关键字高亮和微博表情,查了一些资料,决定记录点东西

先来看下效果图:

像以上这种#话题#,@XXX昵称,HTTP:网页链接等元素,在微博里是被高亮成蓝色效果的。

那么在我们的安卓程序开发中应该如何动态的实现这些效果呢?

其实很简单,我写了个小例子,先来看下效果图:

其实要实现这种效果非常的简单,在Android里已经帮我们封装好了一系列的工具类,例如:

android.text.Spanned

android.text.SpannableString

android.text.SpannableStringBuilder

SpannableString和 SpannableStringBuilder可以用来设置不同的Span,可以很容易的实现个性化TextView,比如粗体,斜体,前景色,背景色,字体大小,字体风格等等,android.text.style.*中定义了很多的Span类型可供使用。

其实也没什么好说的,这只是个工具类,只需要掌握他的一般使用方法就可以了,这里直接上代码(附注释)

 package com.example.spannabletest;

 import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern; import android.app.Activity;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.ForegroundColorSpan;
import android.text.style.ImageSpan;
import android.text.style.RelativeSizeSpan;
import android.widget.TextView; public class MainActivity extends Activity { private TextView textView; //待转换字符串
private String info="#我爱JAVA#我的微博名:@Balla_兔子 [兔子]http://weibo.com/lichenwei1992"; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView=(TextView) findViewById(R.id.tx); /**
* 在Android里提供了许多个性化TextView内容的工具类, 使用这些类可以代替常规String。
* android.text.Spanned
* android.text.SpannableString
* android.text.SpannableStringBuilder
*
* 由于Spannable等类最终都实现了CharSequence接口,所以可以直接把SpannableString和SpannableStringBuilder通过TextView.setText()设置给TextView。
*/ //实例化一个Spannable对象
SpannableString spannableString=new SpannableString(info);
//通过setSpan()方法可以用来定义不同的样式内容
//设置字体
//方式一:直接定位
spannableString.setSpan(new ForegroundColorSpan(Color.BLUE), 0, 8, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//方式二:配合String工具类定位
spannableString.setSpan(new ForegroundColorSpan(Color.BLUE), info.indexOf("@"), info.indexOf(" "), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//方式三,利用正则表达式匹配定位
Map<String,Integer> map=getHttpPostion();
spannableString.setSpan(new ForegroundColorSpan(Color.BLUE),map.get("start"), map.get("end"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //设置字体大小
spannableString.setSpan(new RelativeSizeSpan((float) 1.5),map.get("start"),info.length(),Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//设置图片表情
Drawable drawable=getResources().getDrawable(R.drawable.d_tuzi);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
spannableString.setSpan(new ImageSpan(drawable), info.indexOf("["), info.indexOf("]")+1, Spanned.SPAN_INCLUSIVE_INCLUSIVE); textView.setText(spannableString); } public Map<String,Integer> getHttpPostion(){
Map<String,Integer> map=new HashMap<String,Integer>();
Pattern pattern=Pattern.compile("http:.*");
Matcher matcher=pattern.matcher(info);
if(matcher.find()){
map.put("start", matcher.start());
map.put("end", matcher.end());
}
return map; } }

使用方法:

1、要使用个性化TextView的时候,我们需要创建一个SpannableString或SpannableStringBuilder,它们的区别在于 SpannableString像一个String一样,构造对象的时候传入一个String,之后再无法更改String的内容,也无法拼接多个 SpannableString;而SpannableStringBuilder则更像是StringBuilder,它可以通过其append()方法来拼接多个String。

SpannableString类:

SpannableStringBuffer类:

2、创建完Spannable对象后,可以为它们设置Span来实现想要的个性化了(SpannableString和SpannableStringBuilder都有一个相同的Span方法)

这里是API:

参数一:Object what(这里是指风格)

  AbsoluteSizeSpan(int size) :设置字体大小,参数是绝对数值,相当于Word中的字体大小。

  RelativeSizeSpan(float proportion) :设置字体大小,参数是相对于默认字体大小的倍数。

  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在使用的时候通常只传上面所说明的构造参数即可,不需要设置其他的属性,如果需要的话,也可以对它们设置其他的属性,详情可以参见API文档。

参数二和三:(int start,int end)

这里是指个性化匹配的位置:这里有很多种方式去实现,例如直接写死位置,也可以和String类的一些方法配合使用,比如:indexOf(),也可以写个正则匹配方法,如果要匹配多次可以把这些匹配存入一个Map集合,具体情况,根据自己的项目抉择哈。

参数四:(int flags)

常用的有:(这里理解起来就好像数学中的区间定义,开区间或是闭区间)

  Spanned.SPAN_EXCLUSIVE_EXCLUSIVE --- 不包含两端start和end所在的端点

  Spanned.SPAN_EXCLUSIVE_INCLUSIVE --- 不包含端start,但包含end所在的端点

  Spanned.SPAN_INCLUSIVE_EXCLUSIVE --- 包含两端start,但不包含end所在的端点

  Spanned.SPAN_INCLUSIVE_INCLUSIVE--- 包含两端start和end所在的端点

还有一些其他的属性,这里就不一一列举了,大家自己翻看API文档吧。

再来翻看下SpannableString和SpannableStringBuffer的源码,我们可以发现,他们都实现了CharSequence接口,所以他们可以直接在TextView.setText()中设置

好了,这里只是抛砖引玉,给出了最基础的使用方法,具体项目中还需要去灵活的变换使用方法。

最新文章

  1. swift 定时器的使用
  2. JSON.parse()和JSON.stringify()使用介绍
  3. Ubuntu 系统密码相关问题
  4. Navi.Soft30.开放平台.聚合.开发手册
  5. Go语言实现HashSet
  6. 23Spring_JdbcTemplate来实现单表的增删改查
  7. sql中with as的用法练习
  8. NetAnalyzer笔记 目录
  9. 整理的一些数据库不容易想到的SQL语句实例一
  10. Prim算法模板
  11. js监听用户思否在当前页面
  12. db2空值、null
  13. 解决Win7(x64)Anaconda3报错:AttributeError: &#39;_NamespacePath&#39; object has no attribute &#39;sort&#39;
  14. Servlet过滤器和监听器配置范例
  15. Java多态的一些陷阱
  16. 用c写了个后台扫描
  17. 解决IE6双倍边距BUG
  18. linux下order by 报出ORDER BY clause is not in SELECT list
  19. 小甲鱼Python笔记(类)
  20. GridhEH 选择勾CheckBox

热门文章

  1. VS2008 编译 libpng库
  2. Windows10系统重置网络设置
  3. Codeforces Round #408 (Div. 2) 题解【ABCDE】
  4. [Beego模型] 二、CRUD 操作
  5. perf 安装到分析
  6. java泛型-自定义泛型方法与类型推断总结
  7. 三大分析法——SWOT、PEST、波特五力
  8. .Net Core邮件发送之MailKit
  9. 奇怪吸引子---LorenaMod1
  10. 如何将Revit明细表导出为Excel文档