安卓开发笔记——个性化TextView(新浪微博)
这几天在仿写新浪微博客户端,在处理微博信息的时候需要处理关键字高亮和微博表情,查了一些资料,决定记录点东西
先来看下效果图:


像以上这种#话题#,@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()中设置


好了,这里只是抛砖引玉,给出了最基础的使用方法,具体项目中还需要去灵活的变换使用方法。
安卓开发笔记——个性化TextView(新浪微博)的更多相关文章
- 安卓开发笔记——丰富多彩的TextView
随手笔记,记录一些东西~ 记得之前写过一篇文章<安卓开发笔记——个性化TextView(新浪微博)>:http://www.cnblogs.com/lichenwei/p/4411607. ...
- 安卓开发笔记——自定义广告轮播Banner(实现无限循环)
关于广告轮播,大家肯定不会陌生,它在现手机市场各大APP出现的频率极高,它的优点在于"不占屏",可以仅用小小的固定空位来展示几个甚至几十个广告条,而且动态效果很好,具有很好的用户& ...
- 安卓开发笔记——关于开源项目SlidingMenu的使用介绍(仿QQ5.0侧滑菜单)
记得去年年末的时候写过这个侧滑效果,当时是利用自定义HorizontalScrollView来实现的,效果如下: 有兴趣的朋友可以看看这篇文件<安卓开发笔记——自定义HorizontalScro ...
- 安卓开发笔记——打造万能适配器(Adapter)
为什么要打造万能适配器? 在安卓开发中,用到ListView和GridView的地方实在是太多了,系统默认给我们提供的适配器(ArrayAdapter,SimpleAdapter)经常不能满足我们的需 ...
- 安卓开发笔记——深入Activity
在上一篇文章<安卓开发笔记——重识Activity >中,我们了解了Activity生命周期的执行顺序和一些基本的数据保存操作,但如果只知道这些是对于我们的开发需求来说是远远不够的,今天我 ...
- 安卓开发笔记——关于Handler的一些总结(上)
接上篇文章<安卓开发笔记——关于AsyncTask的使用>,今天来讲下在安卓开发里"重中之重"的另一个异步操作类Handler. 今天打算先讲下关于Handler的一些 ...
- 安卓开发笔记——Fragment+FragmentTabHost组件(实现新浪微博底部菜单)
记得之前写过2篇关于底部菜单的实现,由于使用的是过时的TabHost类,虽然一样可以实现我们想要的效果,但作为学习,还是需要来了解下这个新引入类FragmentTabHost 之前2篇文章的链接: 安 ...
- 安卓开发笔记——Fragment+ViewPager组件(高仿微信界面)
什么是ViewPager? 关于ViewPager的介绍和使用,在之前我写过一篇相关的文章<安卓开发复习笔记——ViewPager组件(仿微信引导界面)>,不清楚的朋友可以看看,这里就不再 ...
- 安卓开发笔记——TabHost组件(二)(实现底部菜单导航)
上面文章<安卓开发复习笔记——TabHost组件(一)(实现底部菜单导航)>中提到了利用自定义View(ImageView+TextView)来设置一个底部菜单的样式 这边再补充一种更为灵 ...
随机推荐
- [NOIp2015提高组]跳石头
OJ题号:洛谷2678 思路:贪心+二分. 从前往后扫,一旦这个石头到上一个选的石头的距离小于二分的值就把这块石头移走. #include<cstdio> #include<queu ...
- [Visual Studio] 自定义类模板
1.找到vs2015/vs2012/vs2017的安装目录下:Common7\IDE\ItemTemplates\CSharp\Code\2052\Class 2.打开Class.cs文件 using ...
- dataGridView使用指南系列一、回车换行或换列完美解决方案
在使用datagridview控件时,默认按回车是跳转到下一行的当前列的,要想让按回车跳转到同一行的下一列该怎么做呢? 百度搜索了一下,大都是使用该控件的key_down事件和CellEndEdit进 ...
- ios webview下纯JS实现长按
app,其中有长按LI列表弹出菜单,只要清楚五个方法就行:ontouchstart.ontouchmove.ontouchend.setTimeout.clearTimeout 1.首先在我们按下手指 ...
- 1.Linux进程--进程标识号
函数原型 pid_t fork(void); fork的奇异之处在于它被调用一次,却返回两次,它可能有三种不同的返回值: 1.在父进程中.fork返回新创建的子进程的PID 2.在子进程中,fork返 ...
- 移动电源、3G路由拆机
这款电源4400mAh,淘宝也就八十元左右,可以作为无线路由使用,可以插3G网卡,总的来说还算不错,关键是外观精美,网上一堆和华美A100那样的,可惜实在太丑,这款外观虽然漂亮,但是和一百多的相比不支 ...
- Java -Dfile.encoding=UTF-8 干掉乱码
遭遇乱码问题的来龙去脉 这两天写了一个 Java 程序来玩,结果又遭遇了以前遇到过很多次的乱码问题,具体描述一下:在 Mac 系统里面,常用的 Java 程序启动方式有如下几种:1.通过 eclips ...
- 解锁scott账户方法
装完了数据库,忘了给scott账户解锁.这时可以在sql plus工具里,也可以在控制台通过命令行给scott账户解锁. 在第一种情况下,以system账户+自己安装时设置的密码,登录SQL Plus ...
- gitlab Docker容器创建命令以及从容器中备份gitlab仓库示例
Gitlab容器启动命令: docker run -d --name gitlab --publish : --publish : --hostname gitlab-server --volume ...
- 微软自然语言理解平台LUIS:从零开始,帮你开发智能音箱
今年微软开发者大会Build 2017上展示了一款Invoke智能音箱,受到了媒体和大众的广泛关注.近两年,不少大公司纷纷涉足该领域,使得智能音箱逐渐成为一款热门的人工智能家用电器.智能音箱的兴起也改 ...