TextView 的隐藏技能

TextView 的隐藏技能

字符串资源里变量替换

Android开发中是拒绝硬编码的,我们需要把一些字符串放在xml中当作资源使用,假设有如下情况:

"welcome">你好A,欢迎使用我们的App。

我们在程序中需要使用这个字符串,但是A是一个变量,很常规的办法是取出这个字符串,然后用String的replace方法把A替换成用户的昵称。

其实,在android中有这样一个东西,那就是 XLIFF,全称叫 XML 本地化数据交换格式,英文全称 XML Localization Interchange File Format。

用法也是很简单的,如

"welcome">你好%1$s,欢迎使用我们的App。

程序中只要给变量赋值就可以了,如

String welcome = getString(R.string.welcome, "小调皮");

显示结果就变成了

你好小调皮,欢迎使用我们的App。

%1 s s代表字符串$d代表整数。

下面我再写一个例子

xml配置文件
"tvText">大家好!我叫%1$s请多关照,我今年%2$d岁,我的体重也是%2$dkg
代码实现
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 = "如果有一天,";
String textStr2 = "我悄然离去";
textth.setText(Html.fromHtml(textStr1 + textStr2));

效果如下

我们平常使用TextView的setText()方法传递String参数的时候,其实是调用的public final void setText (CharSequence text)方法:

/**
    * Sets the string value of the TextView. TextView does not 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
    * 
    * Available Resource Types 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使用HTMLtitle>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\">颜色2p><h1>标题1h1><h3>标题2h3><h6>标题3h6><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));
    }

效果图:
Mou icon

可以看出,字体效果是显示出来了,但是图片却没有显示。要实现图片的显示需要使用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文件夹下。

但是需要注意的是,不要大量使用这种自定义字体,因为自定义字体会消耗更多的性能。

你可能感兴趣的:(技术)