Android TextView 点击超链接跳转实现

您所在的位置:网站首页 超链接单击打开 Android TextView 点击超链接跳转实现

Android TextView 点击超链接跳转实现

2023-11-17 19:00| 来源: 网络整理| 查看: 265

前提:之前遇到过一次textview显示url的方式,但是并未深入探究。但是,上个礼拜一个朋友问我如何在textview上面加载url,并且点击跳转到指定页面。当时对这个比较感兴趣也就深入探究了一番。虽然实现了,但是效果并不理想。如果哪位看官对这一点,理解的比较深入,请告诉我一声,谢谢了。 首先 对TextView属性比较熟悉的开发者应该都知道TextView有一个叫做autoLink的属性,可以将符合指定格式的文本转换为可单击的超链接形式,在帮助文档中也可以发现Android给我们提供了如下几种格式:

1、none:表示不进行任何匹配,默认; 2、Web:表示匹配Web Url, 如: 连接地址为http://www.baidu.com会成为可单击跳转的超链接; 3、Email:表示匹配邮件地址, 如:邮件地址为[email protected]会成为可单击的超链接; 4、Phone:表示匹配电话号码,如:点击号码10000会跳到拨号界面; 5、Map:表示匹配地图地址; 6、All:表示将会匹配web、email、phone、map;

如下图所示

TextView autoLink.png

其中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 CREATOR = new Creator() { 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)



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3