这两个差别似乎不是很大,很多属性都是共有的,只不过一个能编辑一个不能。
xml属性:
代码 | 解释 |
---|---|
android:id="@+id/name" | 起个名字 |
android:layout_width="wrap_content" | 控件宽度 |
android:layout_height="wrap_content" | 控件高度 |
android:text="内容" | 控件显示的字符内容 |
android:ems="1" | EditText的宽度为一个中文的宽度即2个字符的宽度 |
android:maxLength="4" | 控件一共最大可含有4个字符 |
android:textColor="@color/black" | 字符颜色 |
android:textSize="12dp" | 字符大小 |
android:textStyle="bold" | 字符格式,bold粗体,italic斜体,normal正常 |
android:singleLine="true" | 只显示一行字符 |
android:shadowColor="@color/colorAccent" | 字符阴影颜色 |
android:autoLink="web" | 当文本为URL链接时,变为可点击的,点击跳转相应类型, 可选值(none/web/email/phone/map/all) |
android:gravity="center“ | 字符内容在控件内部的位置 |
android:layout_margin="10dp" | 距离四周最近控件边框的距离至少为10dp |
android:ellipsize="end" | 文本过长,超出控件大小,可显示省略号,位置可选。”start”—开头;”end”——结尾; ”middle”—-中间; ”marquee” ——以跑马灯的方式显示(动画横向移动) |
android:textIsSelectable="true" | 长摁可以被选中复制操作 |
Java代码属性:
SpannableString其实和String一样,都是一种字符串类型,SpannableString可以直接作为TextView的显示文本,不同的是SpannableString可以通过使用其方法setSpan方法实现字符串各种形式风格的显示,重要的是可以指定设置的区间,也就是为字符串指定下标区间内的子字符串设置格式。
setSpan(Object what, int start, int end, int flags)方法需要用户输入四个参数,what表示设置的格式是什么,可以是前景色、背景色也可以是可点击的文本等等,start表示需要设置格式的子字符串的起始下标,同理end表示终了下标,flags属性就有意思了,共有四种属性:
Spanned.SPAN_INCLUSIVE_EXCLUSIVE 从起始下标到终了下标,包括起始下标
Spanned.SPAN_INCLUSIVE_INCLUSIVE 从起始下标到终了下标,同时包括起始下标和终了下标
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE 从起始下标到终了下标,但都不包括起始下标和终了下标
Spanned.SPAN_EXCLUSIVE_INCLUSIVE 从起始下标到终了下标,包括终了下标
SpannableString的setSpan()方法可以同时使用多个,实现多种效果叠加。
下面我们一一解读几种Span常用的格式:
-
ForegroundColorSpan
ForegroundColorSpan,为文本设置前景色,效果和TextView的setTextColor()类似,实现方法如下:
SpannableString spannableString = new SpannableString("设置文字的前景色为淡蓝色");
ForegroundColorSpan colorSpan = new ForegroundColorSpan(Color.parseColor("#0099EE"));
spannableString.setSpan(colorSpan, 9, spannableString.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
textView.setText(spannableString);
设置的区间是9到字符串的最后,也就是图中“淡蓝色”三字。
-
BackgroundColorSpan
BackgroundColorSpan,为文本设置背景色,效果和TextView的setBackground()类,实现方法如下:
SpannableString spannableString = new SpannableString("设置文字的背景色为淡绿色");
BackgroundColorSpan colorSpan = new BackgroundColorSpan(Color.parseColor("#AC00FF30"));
spannableString.setSpan(colorSpan, 9, spannableString.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
textView.setText(spannableString);
-
RelativeSizeSpan
RelativeSizeSpan,设置文字相对大小,在TextView原有的文字大小的基础上,相对设置文字大小,实现方法如下:
SpannableString spannableString = new SpannableString("万丈高楼平地起");
RelativeSizeSpan sizeSpan01 = new RelativeSizeSpan(1.2f);
RelativeSizeSpan sizeSpan02 = new RelativeSizeSpan(1.4f);
RelativeSizeSpan sizeSpan03 = new RelativeSizeSpan(1.6f);
RelativeSizeSpan sizeSpan04 = new RelativeSizeSpan(1.8f);
RelativeSizeSpan sizeSpan05 = new RelativeSizeSpan(1.6f);
RelativeSizeSpan sizeSpan06 = new RelativeSizeSpan(1.4f);
RelativeSizeSpan sizeSpan07 = new RelativeSizeSpan(1.2f);
spannableString.setSpan(sizeSpan01, 0, 1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
spannableString.setSpan(sizeSpan02, 1, 2, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
spannableString.setSpan(sizeSpan03, 2, 3, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
spannableString.setSpan(sizeSpan04, 3, 4, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
spannableString.setSpan(sizeSpan05, 4, 5, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
spannableString.setSpan(sizeSpan06, 5, 6, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
spannableString.setSpan(sizeSpan07, 6, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
textView.setText(spannableString);
-
StrikethroughSpan
StrikethroughSpan,为文本设置中划线,也就是常说的删除线,实现方法如下:
SpannableString spannableString = new SpannableString("为文字设置删除线");
StrikethroughSpan strikethroughSpan = new StrikethroughSpan();
spannableString.setSpan(strikethroughSpan, 5, spannableString.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
textView.setText(spannableString);
看到这有没有小激动,分分钟实现天猫打折优惠效果,有木有?
-
UnderlineSpan
UnderlineSpan,为文本设置下划线,具体实现方法如下:
SpannableString spannableString = new SpannableString("为文字设置下划线");
UnderlineSpan underlineSpan = new UnderlineSpan();
spannableString.setSpan(underlineSpan, 5, spannableString.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
textView.setText(spannableString);
-
SuperscriptSpan
SuperscriptSpan,设置上标,具体实现方法如下:
SpannableString spannableString = new SpannableString("为文字设置上标");
SuperscriptSpan superscriptSpan = new SuperscriptSpan();
spannableString.setSpan(superscriptSpan, 5, spannableString.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
textView.setText(spannableString);
从效果图可以看出,被设置为上标的文字大小和下面的文本文字大小一样,只要我们稍加修饰,结合RelativeSizeSpan设置小字体文本作为上标,分分钟实现指数公式有木有,再也不用2^2+3^2=13这样缺乏审美的数学公式了,是不是超实用?
-
SubscriptSpan
SubscriptSpan,设置下标,功能与设置上标类似,不做过多描述,具体实现方法如下:
SpannableString spannableString = new SpannableString("为文字设置下标");
SubscriptSpan subscriptSpan = new SubscriptSpan();
spannableString.setSpan(subscriptSpan, 5, spannableString.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
textView.setText(spannableString);
-
StyleSpan
StyleSpan,为文字设置风格(粗体、斜体),和TextView属性textStyle类似,实现方法如下:
SpannableString spannableString = new SpannableString("为文字设置粗体、斜体风格");
StyleSpan styleSpan_B = new StyleSpan(Typeface.BOLD);
StyleSpan styleSpan_I = new StyleSpan(Typeface.ITALIC);
spannableString.setSpan(styleSpan_B, 5, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
spannableString.setSpan(styleSpan_I, 8, 10, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
textView.setHighlightColor(Color.parseColor("#36969696"));
textView.setText(spannableString);
-
ImageSpan
ImageSpan,设置文本图片,实现方法如下:
SpannableString spannableString = new SpannableString("在文本中添加表情(表情)");
Drawable drawable = getResources().getDrawable(R.mipmap.a9c);
drawable.setBounds(0, 0, 42, 42);
ImageSpan imageSpan = new ImageSpan(drawable);
spannableString.setSpan(imageSpan, 6, 8, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
textView.setText(spannableString);
这一个是不是很炫酷?再加一个解析算法,将文本中特定的文本转换成特定的表情图片,分分钟实现聊天表情显示效果有木有啊朋友们!
-
ClickableSpan
设置可点击的文本,设置这个属性的文本可以相应用户点击事件,至于点击事件用户可以自定义,就像效果图显示一样,用户可以实现点击跳转页面的效果,具体实现方法如下:
SpannableString spannableString = new SpannableString("为文字设置点击事件");
MyClickableSpan clickableSpan = new MyClickableSpan("http://www.jianshu.com/users/dbae9ac95c78");
spannableString.setSpan(clickableSpan, 5, spannableString.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
textView.setMovementMethod(LinkMovementMethod.getInstance());
textView.setHighlightColor(Color.parseColor("#36969696"));
textView.setText(spannableString);
/***************************************************************/
class MyClickableSpan extends ClickableSpan {
private String content;
public MyClickableSpan(String content) {
this.content = content;
}
@Override
public void updateDrawState(TextPaint ds) {
ds.setUnderlineText(false);
}
@Override
public void onClick(View widget) {
Intent intent = new Intent(MainActivity.this, OtherActivity.class);
Bundle bundle = new Bundle();
bundle.putString("content", content);
intent.putExtra("bundle", bundle);
startActivity(intent);
}
}
代码中我们自定义MyClickableSpan类,继承至ClickableSpan,并重写其中一些方法。ds.setUnderlineText()控制是否让可点击文本显示下划线,很明显,在上面代码中我选择了false,不显示下滑写。onClick点击事件的具体实现方法写在其中。如上代码,我们重写ClickableSpan的onClick方法实现Activity的跳转效果,并传递跳转数据。
注意:使用ClickableSpan的文本如果想真正实现点击作用,必须为TextView设置setMovementMethod方法,否则没有点击相应,至于setHighlightColor方法则是控制点击是的背景色。
-
URLSpan
URLSpan,设置超链接文本,其实聪明的小伙帮在讲到ClickableSpan的时候就能实现超链接文本的效果了,重写onClick点击事件就行,也确实看了URLSpan的源码,URLSpan就是继承自ClickableSpan,也和想象中一样,就是重写了父类的onClick事件,用系统自带浏览器打开链接,具体实现方法如下:
SpannableString spannableString = new SpannableString("为文字设置超链接");
URLSpan urlSpan = new URLSpan("http://www.jianshu.com/users/dbae9ac95c78");
spannableString.setSpan(urlSpan, 5, spannableString.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
textView.setMovementMethod(LinkMovementMethod.getInstance());
textView.setHighlightColor(Color.parseColor("#36969696"));
textView.setText(spannableString);
URLSpanonClick事件的源码如下:
@Override
public void onClick(View widget) {
Uri uri = Uri.parse(getURL());
Context context = widget.getContext();
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName());
try {
context.startActivity(intent);
} catch (ActivityNotFoundException e) {
Log.w("URLSpan", "Actvity was not found for intent, " + intent.toString());
}
}
除此之外,还有MaskFilterSpan可以实现模糊和浮雕效果,RasterizerSpan可以实现光栅效果,因为以上两个使用频率不高,而且效果也不是很明显,就不做详细说明,有兴趣的小伙伴不妨去试一试。
SpannableStringBuilder
应该有不少开发的小伙伴知道StringBuilder,可以使用append()方法实现字符串拼接,非常方便。同样,SpannableString中也有SpannableStringBuilder,顾名思义,就是实现对,SpannableString的一个拼接效果,同样是append()方法,可以实现各种风格效果的SpannableString拼接,非常实用。
TextView的html标签解析
之前讲解Android布局的时候,就已经说明,所有Layout都是View的子类或者间接子类。而TextView也一样,是View的直接子类。它是一个文本显示控件,提供了基本的显示文本的功能,并且是大部分UI控件的父类,因为大部分UI控件都需要展示信息。
如果仅仅是展示文本,那么TextView的作用就太小了,所以它还预定义了一些类似于HTML的标签,通过这些标签可以使TextView控件显示不同的颜色、大小、字体、图片、链接。这些HTML标签都需要android.text.Html类的支持,但是并不包括所有的HTML标签。
常用的可以再TextView中设定的标签有:
- <font>:设置颜色和字体。
- <big>:设置字体大号
- <small>:设置字体小号
- <i>\<b>:斜体\粗体
- <a>:连接网址
- <img>:图片
使用这些标签可以用Html.fromHtml方法将这些标签的字符串转换成CharSequence接口,然后在TextView.setText()中进行设置。如果需要响应设置的HTML标签进行响应,需要设置TextView.setMovementMethod(LinkMovementMethod.getInstance())。
CharSequence为接口类型,大家可能对其有点陌生,但是它的子类肯定会让大家有熟悉的感觉,String、StringBuffer、StringBuilder、SpannableString、SpannableStringBuilder都是其子类,它包括了字符串的所有类,因为面向对象的多态性,在这里把他理解成字符串类的抽象即可。
除了使用HTML标签的方式设定显示文本中的URL地址、邮箱地址、电话等产生超链接出发相应的服务,可以使用android:autoLink属性来设置,以下是android:autoLink属性的介绍:
- None:默认的,不匹配任何连接。
- web:网址。
- email:邮箱。
- phone:电话号码。
- map:匹配映射网址。
- all:匹配所有连接。
TextView显示图片
第二个例子讲解一下在TextView中显示图片的例子,依然是使用HTML标签的方式定义样式,但是使用的是Html.fromHtml()的另外一个重载的静态方法,可以设定<img>标签中的图像资源。
static Spanned fromHtml(String source,Html.ImageGetter imageGetter,Html.TagHandler tagHandler)
对于这个方法,在imageGetter参数中设定<img>标签中的图像资源文件,tagHandler主要是为了处理Html类无法识别的html标签的情况,一般不会用上,传值为null即可。
布局XML文件textvideforimg.xml代码:
1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 android:layout_width="match_parent"
4 android:layout_height="match_parent"
5 android:orientation="vertical" >
6 <TextView
7 android:id="@+id/textImg"
8 android:layout_width="fill_parent"
9 android:layout_height="match_parent"
10 android:layout_margin="10dp" />
11 </LinearLayout>
Activity文件textviewForImgActivity.java代码:
1 package cn.bgxt.textviewdemo;
2
3 import java.lang.reflect.Field;
4
5 import android.R.color;
6 import android.app.Activity;
7 import android.graphics.drawable.Drawable;
8 import android.os.Bundle;
9 import android.text.Html;
10 import android.text.Html.ImageGetter;
11 import android.text.method.LinkMovementMethod;
12 import android.widget.TextView;
13
14 public class textviewForImgActivity extends Activity {
15
16 private TextView textViewImg;
17 public textviewForImgActivity() {
18 // TODO Auto-generated constructor stub
19 }
20
21 @Override
22 protected void onCreate(Bundle savedInstanceState) {
23 // TODO Auto-generated method stub
24 super.onCreate(savedInstanceState);
25 setContentView(R.layout.textvideforimg);
26
27 textViewImg=(TextView)findViewById(R.id.textImg);
28 textViewImg.setTextColor(color.white);
29 textViewImg.setBackgroundColor(color.black);
30 textViewImg.setTextSize(20);
31 //设定HTML标签样式,图片3为一个超链接标签a
32 String html="图像1<img src='image1'/>图像2<img src='image2'/>\n";
33 html+="图像3<a href='http://www,baidu.com'><img src='image3'/></a>";
34 //fromHtml中ImageGetter选择html中<img>的图片资源
35 CharSequence cs=Html.fromHtml(html, new ImageGetter() {
36
37 public Drawable getDrawable(String source) {
38 //source为html字符串中定义的<img>中的src的内容
39 //返回值Drawable就是对应的<img>显示的图片资源
40 Drawable draw=null;
41 if(source.equals("image1"))
42 {
43 draw=getResources().getDrawable(R.drawable.image1);
44 draw.setBounds(0, 0, draw.getIntrinsicWidth(), draw.getIntrinsicHeight());
45 }
46 else if(source.equals("image2"))
47 {
48 //设定image2尺寸等比缩小
49 draw=getResources().getDrawable(R.drawable.image2);
50 draw.setBounds(0, 0, draw.getIntrinsicWidth()/2, draw.getIntrinsicHeight()/2);
51 }
52 else
53 {
54 //使用反射会更简便,无需知道src与资源Id的对应关系
55 draw=getResources().getDrawable(getResourceId(source));
56 draw.setBounds(0, 0, draw.getIntrinsicWidth(), draw.getIntrinsicHeight());
57 }
58 return draw;
59 }
60 }, null);
61 textViewImg.setText(cs);
62 textViewImg.setMovementMethod(LinkMovementMethod.getInstance());
63 }
64
65 public int getResourceId(String source)
66 {
67 try {
68 //使用反射机制,通过属性名称,得到其内的值
69 Field field=R.drawable.class.getField(source);
70 return Integer.parseInt(field.get(null).toString());
71 } catch (Exception e) {
72 // TODO: handle exception
73 }
74 return 0;
75 }
76
77 }
效果截图,其中第三个图片点击会触发浏览器访问百度网址:
功能实现例子:
1.走马灯:
xml:
android:singleLine="true" android:ellipsize="marquee"
java:
TextView textView=findViewById(R.id.zoumadeng); textView.setSelected(true);
2.请阅读《服务协议》和《隐私条款》后注册:
Java:
TextView textView=findViewById(R.id.zoumadeng); SpannableString s1=new SpannableString(textview.getText().toString()); s1.setSpan(new ClickableSpan() { @Override public void onClick(View widget) { ...... 单击事件 ...... }}, 3, 9, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); s1.setSpan(new ClickableSpan() { @Override public void onClick(View widget) { ...... 单击事件 ...... }}, 10, 16, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); textView.setText(s1); textView.setMovementMethod(LinkMovementMethod.getInstance());