rokevin
移动
前端
语言
  • 基础

    • Linux
    • 实施
    • 版本构建
  • 应用

    • WEB服务器
    • 数据库
  • 资讯

    • 工具
    • 部署
开放平台
产品设计
  • 人工智能
  • 云计算
计算机
其它
GitHub
移动
前端
语言
  • 基础

    • Linux
    • 实施
    • 版本构建
  • 应用

    • WEB服务器
    • 数据库
  • 资讯

    • 工具
    • 部署
开放平台
产品设计
  • 人工智能
  • 云计算
计算机
其它
GitHub
  • TextView

TextView

Android中实现TextView超链接五种方式

1. 直接在xml文件中配置autoLink属性

autoLink属性一共有六个值,分别是none(正常),web(将文本识别为一个网址),phone(将文本识别为一个电话号码),mail(将文本识别为一个邮件地址),map(这个,呃,该怎么表述呢?会打开地图应用),all(根据文本自动识别)。一般情况下我们设置为all即可,我们看看,这个时候它就会自动将TextView中的电话号码、邮件地址、网页链接等识别出来,这中方式是最简单的一种。如:


<TextView  
    android:layout_width="fill_parent"  
    android:layout_height="wrap_content"  
    android:autoLink="all"  
    android:text=""
    android:textSize="16dp" />  
    

2. 使用HTML语言

我们知道TextView可以直接显示转换后的HTML,那么借助H5开发经验,我们知道网页中的超链接也可以在TextView中打开,如下: 只要我们写好协议,这个其实也很简单。

tv1.setText(Html.fromHtml("<a href='tel:189xxxx1234'>打电话</a>,<a href='smsto:189xxxx1234'>发短信</a>,<a href='mailto:xxx@sina.com'>发邮件</a>,<a href='http://www.baidu.com'>百度</a>"));    
tv1.setMovementMethod(LinkMovementMethod.getInstance());    

3. 在strings.xml中直接写HTML,然后在TextView的xml中直接引用即可

strings.xml中的定义如下:

<string name="tv4"><a href='tel:189xxxx1234'>打电话</a>,<a href='smsto:189xxxx1234'>发短信</a>,<a href='mailto:xxx@qq.com'>发邮件</a>,<a href='http://www.baidu.com'>百度</a></string> 

TextView的XML定义如下:

<TextView    
        android:id="@+id/tv4"    
        android:layout_width="match_parent"    
        android:layout_height="48dp"    
        android:gravity="center"    
        android:text="@string/tv4"    
        android:textSize="24sp" />    

然后只需要在Activity中设置该TextView为可点击状态即可:

tv4.setMovementMethod(LinkMovementMethod.getInstance());

4. 使用SpannableString实现超链接

SpannableString ss = new SpannableString("打电话,发短信,发邮件,Go百度");    
ss.setSpan(new URLSpan("tel:189xxxx1234"), 0, 3,    
        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);    
ss.setSpan(new URLSpan("smsto:189xxxx1234"), 4, 7,    
        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);    
ss.setSpan(new URLSpan("mailto:xxx@qq.com"), 8, 11,    
        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);    
ss.setSpan(new URLSpan("http://www.baidu.com"), 12, 16,    
        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);    
//SpannableString对象设置给TextView    
tv3.setText(ss);    
//设置TextView可点击    
tv3.setMovementMethod(LinkMovementMethod.getInstance());   

5. 使用SpannableTextView实现

SpannableTextView tv1 = (SpannableTextView) view.findViewById(R.id.tv1);  
  
Span span1 = new Span.Builder("ForegroundSpan, BackgroundSpan, and CustomTypefaceSpan")  
     .foregroundColor(R.color.purple_500)  
     .backgroundColor(R.color.green_500)  
     .typeface(mItalicFont)  
     .build();  
  
tv1.setFormattedText(span1);  

设置多重效果叠加:

SpannableTextView tv2 = (SpannableTextView) view.findViewById(R.id.tv2);  
  
List<Span> spans1 = new ArrayList<>();  
spans1.add(new Span.Builder("ForegroundSpan")  
        .foregroundColor(R.color.red_500)  
        .build());  
spans1.add(new Span.Builder("BackgroundSpan")  
        .backgroundColor(R.color.yellow_500)  
        .build());  
spans1.add(new Span.Builder("ForegroundSpan and BackgroundSpan")  
        .foregroundColor(R.color.orange_500)  
        .backgroundColor(R.color.blue_500)  
        .build());  
spans1.add(new Span.Builder("ForegroundSpan, BackgroundSpan, and CustomTypefaceSpan")  
        .foregroundColor(R.color.green_500)  
        .backgroundColor(R.color.indigo_500)  
        .typeface(mRegularFont)  
        .build());  
  
tv2.setFormattedText(spans1); 

实现无下划线超链接

自定义的 urlspan 继承URLSpan 去掉下划线

//自定义urlspan 去掉下划线   
public class URLSpanNoUnderline extends URLSpan {  
    public URLSpanNoUnderline(String url) {  
        super(url);  
    }  
  
    @Override  
    public void updateDrawState(TextPaint ds) {  
        super.updateDrawState(ds);  
        ds.setUnderlineText(false);  
        ds.setColor(Color.BLACK);  
    }  
}  

文字概念

baseline 基线

文字绘制对齐问题

文字绘制的关键:测量

难点

  1. 纵向文字居中对齐
  2. 左对齐
  3. 精准换行

纵向文字居中对齐

1. Rect

如:让圆中文字居中对齐,会有什么问题?字符变化的时候会有跳动感

paint.setTextSize(Utils.dp2px(100));
paint.setStyle(Paint.Style.FILL);
paint.setTextAlign(Paint.Align.CENTER); // 横向居中
Rect bounds = new Rect();
paint.getTextBounds("text", 0, "text".length,bounds);
float offset = (bounds.top + bounds.bottom) / 2 
canvas.drawText("2048", getWidth() / 2, getHeight() / 2 - offset, paint);

2. fontMetrics

字符变化的时候解决文字跳动的问题

Ascent 上线 Descent 下线

paint.setTextSize(Utils.dp2px(100));
paint.setStyle(Paint.Style.FILL);
paint.setTextAlign(Paint.Align.CENTER); // 横向居中
Rect bounds = new Rect();
paint.getTextBounds("text", 0, "text".length,bounds);
float offset = (fontMetrics.ascent + fontMetrics.descent) / 2
canvas.drawText("2048", getWidth() / 2, getHeight() / 2 - offset, paint);

左对齐

大文字和小文字在左边的时候会有空隙

paint.setTextSize(bigSize);
canvas.drawText("text", 10, 200, paint);
paint.setTextSize(smallSize);
canvas.drawText("text", 10, 200 + spacing, paint);

精准换行

图文混排

Android一个倾斜的TextView,适用于标签效果

https://www.jianshu.com/p/f79f67ff0178

属性

代码设置TextView的TextStyle

setTypeface(Typeface.defaultFromStyle(Typeface.NORMAL));
最近更新:: 2025/10/22 15:36
Contributors: luokaiwen, 罗凯文