TextView 的隐藏技能
字符串资源里变量替换
Android开发中是拒绝硬编码的,我们需要把一些字符串放在xml中当作资源使用,假设有如下情况:
<string name="welcome">你好A,欢迎使用我们的App。</string>
我们在程序中需要使用这个字符串,但是A是一个变量,很常规的办法是取出这个字符串,然后用String的replace方法把A替换成用户的昵称。
其实,在android中有这样一个东西,那就是 XLIFF,全称叫 XML 本地化数据交换格式,英文全称 XML Localization Interchange File Format。
用法也是很简单的,如
<string name="welcome">你好%1$s,欢迎使用我们的App。</string>
程序中只要给变量赋值就可以了,如
String welcome = getString(R.string.welcome, "小调皮");
显示结果就变成了
你好小调皮,欢迎使用我们的App。
%1s这里的s代表字符串$d代表整数。
下面我再写一个例子
xml配置文件
<string name="tvText">大家好!我叫%1$s请多关照,我今年%2$d岁,我的体重也是%2$dkg</string>
代码实现
String tvText = getString(R.string.tvText,"android",60);
显示
大家好!我叫android请多关照,我今年60岁,我的体重也是60dkg
TextView中设置Html
下面先说说TextView支持的HTML的标签有什么
HTML支持的标签
<a href="..."> //定义链接内容
<b> //定义粗体文字 b 是blod的缩写
<big> //定义大字体的文字
<blockquote> //引用块标签
<br> //定义换行
<cite> //表示引用的URI
<dfn> //定义标签 dfn 是defining instance的缩写
<div align="...">
<em> //强调标签 em 是emphasis的缩写
<font size="..." color="..." face="...">
<h1>
<h2>
<h3>
<h4>
<h5>
<h6>
<i> //定义斜体文字
<img src="...">
<p> // 段落标签,里面可以加入文字,列表,表格等
<small> //定义小字体的文字
<strike> // 定义删除线样式的文字 不符合标准网页设计的理念,不赞成使用. strike是strikethrough的缩写
<strong> //重点强调标签
<sub> //下标标签 sub 是subscript的缩写
<sup> //上标标签 sup 是superscript的缩写
<tt> //定义monospaced字体的文字 不赞成使用. 此标签对中文没意义 tt是teletype or monospaced text style的意思
<u> //定义带有下划线的文字 u是underlined text style的意思
来看一个简单的例子吧
TextView textth = (TextView) findViewById(R.id.textth);
String textStr1 = "<font color=\"#123569\">如果有一天,</font>";
String textStr2 = "<font color=\"#00ff00\">我悄然离去</font>";
textth.setText(Html.fromHtml(textStr1 + textStr2));
效果如下
我们平常使用TextView的setText()方法传递String参数的时候,其实是调用的public final void setText (CharSequence text)方法:
/**
* Sets the string value of the TextView. TextView <em>does not</em> accept
* HTML-like formatting, which you can do with text strings in XML resource files.
* To style your strings, attach android.text.style.* objects to a
* {@link android.text.SpannableString SpannableString}, or see the
* <a href="{@docRoot}guide/topics/resources/available-resources.html#stringresources">
* Available Resource Types</a> documentation for an example of setting
* formatted text in the XML resource file.
*
* @attr ref android.R.styleable#TextView_text
*/
@android.view.RemotableViewMethod
public final void setText(CharSequence text) {
setText(text, mBufferType);
}
而String类是CharSequence的子类,在CharSequence子类中有一个接口Spanned,即类似html的带标记的文本,我们可以用它来在TextView中显示html。但在上面Android源码注释中有提及TextView does not accept HTML-like formatting。
android.text.Html类共提供了三个方法,可以到Android帮助文档查看。
public static Spanned fromHtml (String source)
public static Spanned fromHtml (String source, Html.ImageGetter imageGetter, Html.TagHandler tagHandler)
public static String toHtml (Spanned text)
通过使用第一个方法,可以将Html显示在TextView中:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView tv=(TextView)findViewById(R.id.textView1);
String html="<html><head><title>TextView使用HTML</title></head><body><p><strong>强调</strong></p><p><em>斜体</em></p>"
+"<p><a href=\"http://www.dreamdu.com/xhtml/\">超链接HTML入门</a>学习HTML!</p><p><font color=\"#aabb00\">颜色1"
+"</p><p><font color=\"#00bbaa\">颜色2</p><h1>标题1</h1><h3>标题2</h3><h6>标题3</h6><p>大于>小于<</p><p>" +
"下面是网络图片</p><img src=\"http://avatar.csdn.net/0/3/8/2_zhang957411207.jpg\"/></body></html>";
tv.setMovementMethod(ScrollingMovementMethod.getInstance());//滚动
tv.setText(Html.fromHtml(html));
}
效果图:
可以看出,字体效果是显示出来了,但是图片却没有显示。要实现图片的显示需要使用Html.fromHtml的另外一个重构方法:public static Spanned fromHtml (String source, Html.ImageGetterimageGetter, Html.TagHandler tagHandler)其中Html.ImageGetter是一个接口,我们要实现此接口,在它的getDrawable(String source)方法中返回图片的Drawable对象才可以。
修改后的代码:
ImageGetter imgGetter = new Html.ImageGetter() {
public Drawable getDrawable(String source) {
Drawable drawable = null;
URL url;
try {
url = new URL(source);
drawable = Drawable.createFromStream(url.openStream(), ""); //获取网路图片
} catch (Exception e) {
return null;
}
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable
.getIntrinsicHeight());
return drawable;
}
};
显示本地图片
ImageGetter imgGetter = new Html.ImageGetter() {
public Drawable getDrawable(String source) {
Drawable drawable = null;
drawable = Drawable.createFromPath(source); //显示本地图片
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable
.getIntrinsicHeight());
return drawable;
}
};
TextView中设置多种字体大小
比如在项目中经常遇到如下UI,
像这样的两种字体大小放到一个TextView中,我们应该如何处理呢?需要用到 android.text 命名空间下的一些与 spannable相关的类和接口。如下:
String text = "您已经连续走了5963步";
int start = text.indexOf(‘5‘);
int end = text.length();
Spannable textSpan = new SpannableStringBuilder(text);
textSpan.setSpan(new AbsoluteSizeSpan(16), 0, start, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
textSpan.setSpan(new AbsoluteSizeSpan(26), start, end - 1, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
textSpan.setSpan(new AbsoluteSizeSpan(16), end - 1, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
TextView textView = (TextView) findViewById(R.id.text);
textView.setText(textSpan);
TextView中设置超链接
这个比较简单,设置我们上边提到的android:autoLink属性,默认为none。该属性的几个常量如下:
代码中的设置方式:setAutoLinkMask(int)。
参数和上边列表对应,分别为:Linkify.WEB_URLS,Linkify.EMAIL_ADDRESSES,Linkify.PHONE_NUMBERS,Linkify.MAP_ADDRESSES,Linkify.ALL
但是需要注意的是,当我们需要定制超链接的跳转时应该怎么做?答案是还是选择Spannable。代码如下:
//将TextView的显示文字设置为SpannableString
testText.setText(getClickableSpan());
//设置该句使文本的超连接起作用
testText.setMovementMethod(LinkMovementMethod.getInstance());
//设置超链接文字
private SpannableString getClickableSpan() {
SpannableString spanStr = new SpannableString("使用该软件,即表示您同意该软件的使用条款和隐私政策");
//设置下划线文字
spanStr.setSpan(new UnderlineSpan(), 16, 20, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//设置文字的单击事件
spanStr.setSpan(new ClickableSpan() {
@Override
public void onClick(View widget) {
startActivity(new Intent(MainActivity.this, UsageActivity.class));
}
}, 16, 20, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//设置文字的前景色
spanStr.setSpan(new ForegroundColorSpan(Color.GREEN), 16, 20, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//设置下划线文字
spanStr.setSpan(new UnderlineSpan(), 21, 25, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//设置文字的单击事件
spanStr.setSpan(new ClickableSpan() {
@Override
public void onClick(View widget) {
startActivity(new Intent(MainActivity.this, PrivacyActivity.class));
}
}, 21, 25, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//设置文字的前景色
spanStr.setSpan(new ForegroundColorSpan(Color.GREEN), 21, 25, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
return spanStr;
}
运行效果如下图:
插入图片
Android中可以使用TextView的drawableXXX属性在文字周围插入图片。图片和文字之间的间距可以通过android:drawablePadding来设置。
xml中属性为:
android:drawableLeft
android:drawableTop
android:drawableRight
android:drawableBottom
代码中的设置方式:setCompoundDrawablesWithIntrinsicBounds(int left, int top, int right, int bottom)。
left,top等需传入资源id,不需要的话传0.
阴影
Android中设置阴影也比较简单,xml中可以这样设置:
android:shadowColor //指定文本阴影的颜色
android:shadowDx //设置阴影横向坐标开始位置
android:shadowDy //设置阴影纵向坐标开始位置
android:shadowRadius //设置阴影的半径。设置为0.1会变成字体的颜色
代码中通过方法public void setShadowLayer (float radius, float dx, float dy, int color)来设置。
我的参数是这样的:
android:shadowColor="#ffffff"
android:shadowDx="15.0"
android:shadowDy="5.0"
android:shadowRadius="2.5"
效果如下图:
字体加粗或者倾斜
在xml布局文件中使用android:textStyle=”bold”可以将文字设置成粗体。在代码中设置的方法是:使用TextPaint的仿“粗体”设置setFakeBoldText为true。示例代码如下:
tv.getPaint().setFakeBoldText(true);
textstyle可设置的属性有:
italic为倾斜,多属性可用”|”分开。
文字过长显示省略号或者跑马灯效果
android:maxEms="6" //限制显示的字符长度
android:singleLine="true" //单行显示
android:ellipsize="end"//在结尾用省略号
android:ellipsize设置当文字过长时,该控件该如何显示。有如下值设置:
- ”start”—–省略号显示在开头;
- ”end”——省略号显示在结尾;
- ”middle”—-省略号显示在中间;
- ”marquee” ——以跑马灯的方式显示(动画横向移动)
android:marqueeRepeatLimit 在ellipsize指定marquee的情况下,设置重复滚动的次数,当设置为marquee_forever时表示无限次。实现需要控件获得焦点。
示例代码:
android:marqueeRepeatLimit="marquee_forever"
android:ellipsize="marquee"
android:singleLine="true"
android:focusableInTouchMode="true"
android:focusable="true"
效果如下:
设置行间距
1、android:lineSpacingExtra
设置行间距,如”3dp”。
2、android:lineSpacingMultiplier
设置行间距的倍数,如”1.2″。
关于字体
我们可以通过设置android:typeface属性来控制字体,可以设置为normal, sans, serif, monospace四种。具体如下:
代码中可以通过setTypeface(Typeface)方法设置。但有时候我们的App可能需要使用特殊的字体,这时候怎么办呢?可以通过如下代码设置:
Typeface mTypeFace = Typeface.createFromAsset(getAssets(), "kaiti.ttf");
textview.setTypeface(mTypeFace);
然后将我们的字体文件放到assets文件夹下。
但是需要注意的是,不要大量使用这种自定义字体,因为自定义字体会消耗更多的性能。