本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《
阿里云开发者社区用户服务协议
》和
《
阿里云开发者社区知识产权保护指引
》。如果您发现本社区中有涉嫌抄袭的内容,填写
侵权投诉表单
进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
前提:之前遇到过一次textview显示url的方式,但是并未深入探究。但是,上个礼拜一个朋友问我如何在textview上面加载url,并且点击跳转到指定页面。当时对这个比较感兴趣也就深入探究了一番。虽然实现了,但是效果并不理想。如果哪位看官对这一点,理解的比较深入,请告诉我一声,谢谢了。
对TextView属性比较熟悉的开发者应该都知道TextView有一个叫做autoLink的属性,可以将符合指定格式的文本转换为可单击的超链接形式,在帮助文档中也可以发现Android给我们提供了如下几种格式:
1、none:表示不进行任何匹配,默认;
2、Web:表示匹配Web Url, 如: 连接地址为
http://www.baidu.com
会成为可单击跳转的超链接;
3、Email:表示匹配邮件地址, 如:邮件地址为
xx@sina.com
会成为可单击的超链接;
4、Phone:表示匹配电话号码,如:点击号码10000会跳到拨号界面;
5、Map:表示匹配地图地址;
6、All:表示将会匹配web、email、phone、map;
如下图所示
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_margin="16dp"
android:text="123"
android:autoLink="phone"/>
其中android:autoLink=" "就是加载的属性
要实现点击textview中url的跳转到指定功能页面的功能,有这样两种功能
1、直接跳转到指定页面(可以直接自定义页面);
2、通过手机浏览器到指定页面
首先,来看跳转到指定页面的写法
public class MainActivity extends AppCompatActivity {
TextView mTxtWeb;
CharSequence mContent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
* 初始化控件
private void initView() {
mTxtWeb = (TextView) findViewById(R.id.txt_web);
String htmlLinkText = "天下"+"www.google.com"+"为公";
mTxtWeb.setText(Html.fromHtml(htmlLinkText));
mTxtWeb.setMovementMethod(LinkMovementMethod.getInstance());
CharSequence text = mTxtWeb.getText();
if (text instanceof Spannable) {
int end = text.length();
Spannable sp = (Spannable) mTxtWeb.getText();
URLSpan[] urls = sp.getSpans(0, end, URLSpan.class);
SpannableStringBuilder style = new SpannableStringBuilder(text);
style.clearSpans();
for (final URLSpan url : urls) {
//最主要的一点
CustomClickUrlSpan myURLSpan = new CustomClickUrlSpan(url.getURL(), new CustomClickUrlSpan.OnLinkClickListener() {
@Override
public void onLinkClick(View view) {
Intent intent= new Intent(this,WebActivity.class);
intent.putExtra("url",url.getURL());
startActivity(intent);
style.setSpan(myURLSpan, sp.getSpanStart(url), sp.getSpanEnd(url), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
mTxtWeb.setText(style);
其中CustomClickUrlSpan,是点击url跳转,其中传入一个url,一个自定义接口,达到跳转到指定页面的目的。
public class CustomClickUrlSpan extends ClickableSpan {
private String url;
private OnLinkClickListener mListener;
public CustomClickUrlSpan(String url, OnLinkClickListener listener) {
this.url=url;
this.mListener=listener;
@Override
public void onClick(View widget) {
if (mListener!=null){
mListener.onLinkClick(widget);
* 跳转链接接口
public interface OnLinkClickListener{
void onLinkClick(View view);
其中ClicableSpan是系统的方法,其中定义了一个抽象点击的方法(来看看系统源码)
public abstract class ClickableSpan extends CharacterStyle implements UpdateAppearance {
private static int sIdCounter = 0;
private int mId = sIdCounter++;
* Performs the click action associated with this span.
* 这个是点击方法
public abstract void onClick(View widget);
* Makes the text underlined and in the link color.
@Override
public void updateDrawState(TextPaint ds) {
//这个是设置url颜色
ds.setColor(ds.linkColor);
//这个是设置是否有下划线
ds.setUnderlineText(true);
* Get the unique ID for this span.
* @return The unique ID.
* @hide
public int getId() {
return mId;
当然也有简单的写法,比如:
* 点击跳转
private class MyURLSpan extends ClickableSpan {
private String mUrl;
MyURLSpan(String url) {
mUrl = url;
@Override
public void onClick(View widget) {
Toast.makeText(MainActivity.this, mContent.toString(), Toast.LENGTH_LONG).show();
第二种用的内部类的方法,但是会有局限性,会让主页变得太繁琐,也会让跳转受限,为了让代码看着清晰简洁,所以推荐使用第一种方法。(个人理解,不对的还请指正)
其次,通过浏览器跳转到指定页面(并取消下划线)
public class CustomUrlSpan extends UnderlineSpan implements Parcelable {
String url;
public CustomUrlSpan(String url) {
this.url = url;
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
if (ds != null) {
ds.setUnderlineText(false);
@Override
public int describeContents() {
return 0;
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.url);
protected CustomUrlSpan(Parcel in) {
super(in);
this.url = in.readString();
public static final Creator<CustomUrlSpan> CREATOR = new Creator<CustomUrlSpan>() {
public CustomUrlSpan createFromParcel(Parcel source) {
return new CustomUrlSpan(source);
public CustomUrlSpan[] newArray(int size) {
return new CustomUrlSpan[size];
一定要实现Parcelable接口,要不会有错误提示(下面是activity中的用法,其中通过浏览器跳转到指定页面,并且取消了下划线)。
* 初始化控件
private void initView() {
mTxtWeb = (TextView) findViewById(R.id.txt_web);
String htmlLinkText = "天下"+"www.google.com"+"为公";
mTxtWeb.setText(Html.fromHtml(htmlLinkText));
mTxtWeb.setMovementMethod(LinkMovementMethod.getInstance());
CharSequence text = mTxtWeb.getText();
if (text instanceof Spannable) {
int end = text.length();
Spannable sp = (Spannable) mTxtWeb.getText();
URLSpan[] urls = sp.getSpans(0, end, URLSpan.class);
SpannableStringBuilder style = new SpannableStringBuilder(text);
style.clearSpans();
for (final URLSpan url : urls) {
CustomUrlSpan myURLSpan = new CustomUrlSpan(url.getURL());
style.setSpan(myURLSpan, sp.getSpanStart(url), sp.getSpanEnd(url), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
mTxtWeb.setText(style);
最后(还有一点比较困惑)
UnderlineSpan和ClickableSpan都有设置取消下划线的方法(updateDrawState),重写了方法之后,UnderlineSpan取消了下划线,但是ClickableSpan却取消不了这一点比较困惑。
看源码可以看到UnderlineSpan和ClickableSpan都是继承CharacterStyle,并且有一个抽象方法updateDrawState(),那么直接继承CharacterStyle,然后再自定义一个跳转接口可否实现跳转到指定接口呢,经过试验之后还是会有些许不尽如人意。如果哪位仁兄对这一点比较了解,还请告诉我一声,不胜感激。
对于我们来说,不管做什么事情应该尽自己最大努力去做好,事事都怕认真二字
引用知乎上面的一段话就是:
如果天空是黑暗的,那就摸黑生存;如果发出声音是危险的,那就保持沉默;如果自觉无力发光的,那就蜷伏于墙角。但不要习惯了黑暗就为黑暗辩护;不要为自己的苟且而得意;不要嘲讽那些比自己更勇敢热情的人们。我们可以卑微如尘土,不可扭曲如蛆虫。——季业
推荐一个探讨技术的技术群(493180098)
Android中TextView字体加粗小技巧
开发中经常会遇到字体加粗的需求,在使用系统字体的情况下,我们一般是通过在布局文件中给TextView设置`android:textStyle="bold"`属性。
如果你们的设计师小姐姐不想使用Android的这种加粗效果,只是想要接近于`PingFang SC Medium`的效果,那么TextView的`bold`就有点没脸看了。
tinyvvampirepudge