文本控件
显示富文本(URL、不同大小、字体、颜色的文本)
在TextView中预定义了一些类似HTML标签(不区分大小写),通过这些标签,我们可以使TextView控件显示不同的颜色、大小、字体的文字。
常见的标签如下:
名称 | 描述 |
<font> |
设置颜色和字体 ,只支持color和face两个属性 |
<big> |
大号字体 |
<small> |
小号字体 |
<i> |
斜体 |
<b> |
粗体 |
<tt> |
等宽字体(Monospace) |
<br> |
换行(行与行之间没有空行),相当于\n |
<p> |
换行(行与行之间有空行),相当于\n\n. 对于带有标签的文本,直接使\n无法换行,只能使用<br> 或者<p> |
<a> |
超链接 |
<img> |
插入图像,只有一个src属性 |
虽然和HTML标签类似,但是并不具备HTML标签的全部功能。
不能将带有标签的字符串直接使用TextView.setText()的方法进行设置,需要使用
不能将带有标签的字符串直接使用TextView.setText()的方法进行设置,需要使用Html.fromHtml()将带有标签的字符串转换成CharSequence对象,然后再使用TextView.setText()方法进行设置。
如果想要在显示的文本中将URL、Email、电话号码等特殊内容高亮显示,并在单击的时候触发相关的动作(URL会调用浏览器显示网址,电话号码会在拨号界面显示电话号),可以通过设置<TextView>标签的android.autoLink属性来实现
名称 | 描述 |
none | 不匹配任何链接(默认值) |
web | 匹配Web网址 |
匹配Email | |
phone | 匹配电话号码 |
map | 匹配映射地址 |
all | 匹配所有的连接 |
Demo:
android:autoLink=”all”
<!--用于显示不同颜色、字体、大小的文字--> <TextView android:id="@+id/id_tv_richText1" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <!--用于显示带URL地址、Email地址、电话号码的文字--> <TextView android:id="@+id/id_tv_richText2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:autoLink="all"/>
public class RichTextViewAct extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_rich_text_view); init(); } private void init() { TextView textView1 = (TextView) findViewById(R.id.id_tv_richText1); TextView textView2 = (TextView) findViewById(R.id.id_tv_richText2); String html = "<font color='red'>I Love Android</font><br>"; html += "<font color='#0000FF'><big><i>I Love Android</i></big></font><p>"; html += "<font color='@" + android.R.color.holo_green_dark + "'><tt><b><big><u>I Love Android</u></big></b></tt></font><p>"; html += "<big><a href='http://www.baidu.com'>百度</a></big>"; Log.e("html内容:", html); // 将预定义标签的字符串转换成CharSequence对象 CharSequence charSequence = Html.fromHtml(html); Log.e("charSequence:", charSequence.toString()); // 为第一个TextView设置文本 textView1.setText(charSequence); // 这行代码只管重要,没有,无法单击链接调用浏览器显示网页 textView1.setMovementMethod(LinkMovementMethod.getInstance()); // 第二个TextVie要显示的文本 StringBuffer sb = new StringBuffer(); sb.append("我的URL: http://www.baidu.com\n"); sb.append("我的Email: tttt@gmail.com\n"); sb.append("我的电话:12345678909"); textView2.setText(sb.toString()); textView2.setMovementMethod(LinkMovementMethod.getInstance()); } }
注意
在调用setText方法设置文本完成后,还需要调用 setMovementMethod方法设置一个MovementMethod对象。 由于本例中<a>标签是链接,因此,需要使用LinkMovementMethod.getInstance()方法获得MovementMethod对象,该对象可以使单击浏览器时显示指定的网页,如果不设置MovementMethod对象,虽然可以正常显示a标签指定的链接,但是单击链接任何反应。
在TextView中显示 表情图像和文字
<img>标签可以实现。
img标签只有一个src属性,该属性原则上应该指向一个图像地址或可以找到某个图像资源的唯一标识,但是系统并不会直接根据src属性所指的值自动获取和显示图像,需要开发人员解析。 解析src属性值的工作需要在ImageGetter对象的getDrawable方法中完成。
ImageGetter是个接口。使用过Html.fromHtml方法的如下重载形式会比较熟悉它。
public static Spanned fromHtml(String source,ImageGetter imageGetter ,TagHandler tagHandler);
fromHtml方法有如下三个参数:
source:包含Html标签的字符串
imageGetter:ImageGetter对象。当系统解析到img标签时就是调用ImageGetter对象的getDrawable方法,并将src属性传入getDrawable方法中。至于src属性值的具体含义,就要在getDrawable方法中确定了。 getDrawable方法返回的是一个Drawable对象。我们可以从res/drawable资源、SD卡或者网络获得资源,并封装成Drawable对象。
tagHandler:TagHandler对象,这个参数使用的并不多。当系统处理每一个标签的时候都会调用该对象的handleTag方法,如果不是用该参数,可以设置为null.
Demo: 5张图片,存放在res/drawable文件夹下,在一个TextView中以不同的大小显示这5张图片,并在其中插入相应的文字。
由于无法直接使用文件名来引用res/drawable中的图像资源,我们使用反射技术从R.drawable类中通过图像资源名称获取对应的图像资源ID,实现的原理就是R.drawable类中的相应的资源ID变量名就是图像文件的文件名。
public class MultTextPicAct extends Activity { private TextView tv_textAndPic; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_mult_text_pic); initView(); } /** * 初始化视图 */ private void initView() { // 组件初始化 tv_textAndPic = (TextView) findViewById(R.id.id_tv_textAndPic); tv_textAndPic.setTextSize(20f); tv_textAndPic.setBackgroundColor(Color.WHITE); // 定义图文混编 String html = "图片1<img src='flag_mark_blue'/>图片2<img src='flag_mark_gray'/><p>"; html += "图片3<img src='tag_blue'/><br>"; html += "图片4<a href='http://www.baidu.com'><img src='tag_orange'/></a><p>"; html += "图片5<img src='tag_red'/>"; //使用Html.fromHtml()转换包含Html标签的文本,需要指定第二个参数 CharSequence charSequence = Html.fromHtml(html, new Html.ImageGetter() { @Override public Drawable getDrawable(String source) { // 装载图像资源 Drawable drawable = getResources().getDrawable(getResourceId(source)); // 第三个图片按50%等比压缩 ,其余按原大小显示 if ("tag_blue".equals(source)) { drawable.setBounds(0, 0, drawable.getIntrinsicWidth() / 2, drawable.getIntrinsicHeight() / 2); } else { drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); } return drawable; } }, null); tv_textAndPic.setText(charSequence); // 有<a>超链接标签,需设置LinkMovementMethod,否则点击无相应 tv_textAndPic.setMovementMethod(LinkMovementMethod.getInstance()); } /** * 利用反射从R.drawable类中通过图像资源名称获取对应的图像资源ID * * @param name 表示res/drawable中的图像文件名(不含扩展名) * @return 图像资源ID */ private int getResourceId(String name) { try { // 根据资源的ID变量名(也就是图像资源的文件名),获得Field字段 Field field = R.drawable.class.getField(name); // 取得并返回资源ID(静态变量)的值 return Integer.valueOf(field.get(null).toString()); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return 0; } }
注意:在getDrawable方法中获取到图像资源的drawable对象后,必须使用Drawable.setBounds方法设置图像的显示区域,否则显示区域的面积为0,也就不会在TextView中显示图像了。其中第三个图像等比缩小了50%,显示效果如下
单击链接弹出Activity
我们知道通过<a>标签以及TextView自动识别的特殊文本(网址 电话 Email等),这些都可以通过单击操作来触发不同的动作。虽然这些单击动作已经可以满足大部分的需求了,但是如果要想在单击链接的时候执行任意的自定义的动作,就需要学习下面的内容了。
在Android中,Span表示一段文本的效果,例如链接形式,图像,带颜色的文本等。
所有的Span类都在android.text.style包中。
Demo:
准备一个TextView,点击跳转到Activity。
我们使用SpannableString对象来设置Span。
SpannableString和SpannableBuilder的区别:SpannableString不允许修改文本,只允许设置Span,而SpannableBulilder既允许修改文本,也允许设置Span。
public class Jump2Activity extends Activity { private TextView tv_jump ; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_jump2); initData(); } /** * 点击TextView弹出Activity */ private void initData() { tv_jump = (TextView)findViewById(R.id.id_tv_jump2Act); String text = "显示Activity"; // 将文本转换成SpannableString对象 SpannableString spannableString = new SpannableString(text); // 将text中的所有文本设置成ClickableSpan对象,并实现onClick方法 spannableString.setSpan(new ClickableSpan() { // 在onClick方法中可以编写单击链接时要执行的动作 @Override public void onClick(View widget) { startActivity(new Intent(Jump2Activity.this,JumpTerminalAct.class)); } },0,text.length() , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); // 设置控件显示内容 tv_jump.setText(spannableString); // 在点击链接时凡是要有执行的动作,都必须要设置MovementMethod对象 tv_jump.setMovementMethod(LinkMovementMethod.getInstance()); } }
方法说明setSpan 4个参数
public void setSpan(Object what, int start, int end, int flags) { super.setSpan(what, start, end, flags); }
第一个参数需要设置一个ClickableSpan对象
第二个和第三个参数表示要设置成Span的某段文本的起始位置和终止位置。
第四个参数是一个标志,在本例中设置成了Spanned.SPAN_EXCLUSIVE_EXCLUSIVE,该标志在TextView中的意义不大,单在EditText控件中表示的含义:在当前Span效果的前后输入字符串时并不应用Span的效果。
还有其他的几个值:
Spanned.SPAN_EXCLUSIVE_INCLUSIVE :在Span前面输入的字符不应用Span的效果,后面输入的字符应用Span的效果
Spanned.SPAN_INCLUSIVE_INCLUSIVE:在Span前面输入的字符应用Span的效果,后面输入的字符不应用Span的效果
Spanned.SPAN_INCLUSIVE_EXCLUSIVE:在Span前后输入的字符都应用Span的效果。