Android如何通过TextView实现超链接的跳转

autoLink属性

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

这里写图片描述

拦截超链接

点击web地址时打开后跳转的是手机自带的浏览器,如果希望点击web地址时可以跳转到应用本身的一个WebView界面,那么此时又该如何实现呢

总之在经过一系列的翻阅跟TextView相关的源码和帮助文档后,发现我们可以通过借助Spannable来获取URLSpan数组然后可以通过遍历获取所有的url地址,最后通过给Spannable设置自定义的ClickableSpan来进行跳转

主要代码如下:

public class MainActivity extends Activity {
    TextView textView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textView = (TextView)findViewById(R.id.text);
        interceptHyperLink(textView);
    }

    /**
     * 拦截超链接
     * @param tv
     */
    private void interceptHyperLink(TextView tv) {
        tv.setMovementMethod(LinkMovementMethod.getInstance());
        CharSequence text = tv.getText();
        if (text instanceof Spannable) {
            int end = text.length();
            Spannable spannable = (Spannable) tv.getText();
            URLSpan[] urlSpans = spannable.getSpans(0, end, URLSpan.class);
            if (urlSpans.length == 0) {
                return;
            }

            SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(text);
            // 循环遍历并拦截 所有http://开头的链接
            for (URLSpan uri : urlSpans) {
                String url = uri.getURL();
                if (url.indexOf("http://") == 0) {
                    CustomUrlSpan customUrlSpan = new CustomUrlSpan(this,url);
                    spannableStringBuilder.setSpan(customUrlSpan, spannable.getSpanStart(uri),
                            spannable.getSpanEnd(uri), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
                }
            }
            tv.setText(spannableStringBuilder);
        }
    }

    public class CustomUrlSpan extends ClickableSpan {

        private Context context;
        private String url;
        public CustomUrlSpan(Context context,String url){
            this.context = context;
            this.url = url;
        }

        @Override
        public void onClick(View widget) {
            // 在这里可以做任何自己想要的处理
            Intent intent = new Intent(context,WebViewActivity.class);
            intent.putExtra("weburl",url);
            context.startActivity(intent);
        }
    }
}

2)去除超链接的下划线

从源码中可以发现,超链接中的下划线是通过TextPaint的setUnderlineText方法来实现的,也就是说如果我们想去除超链接中的下划线的话可以通过自定义一个继承自ClickableSpan的类然后重写其updateDrawState方法,在该方法中将TextPaint的setUnderlineText方法设为false,最后再将该自定义的ClickableSpan设置到的相应的TextView中即可

原则上来说通过自定义一个继承自ClickableSpan的类是可以去除超链接的下划线,但是,在这里我将使用跟ClickableSpan类似的一个类UnderlineSpan来实现

1)首先自定义一个继承自UnderlineSpan类的NoUnderlineSpan类并重写父类的updateDrawState方法,然后在该方法中将TextPaint的setUnderlineText方法设为false,主要代码如下

    private class NoUnderlineSpan extends UnderlineSpan {

        @Override
        public void updateDrawState(TextPaint ds) {
            ds.setUnderlineText(false);
        }
    }

2)在需要去除超链接下划线的Activity中的相应TextView后设置如下内容:

private void removeHyperLinkUnderline(TextView tv) {
        CharSequence text = tv.getText();
        if(text instanceof Spannable){
            Log.i("test","true");
            Spannable spannable = (Spannable) tv.getText();
            NoUnderlineSpan noUnderlineSpan = new NoUnderlineSpan();
            spannable.setSpan(noUnderlineSpan,0,text.length(), Spanned.SPAN_MARK_MARK);
        }
    }

效果
这里写图片描述

自定义链接

除了以上通过添加autoLink属性并设置web值实现超链接以外,android还给我们提供了一个Linkify类来自定义超链接,并且从帮助文档中可以看出Linkify还提供了一大堆添加自定义模式的方法

这里写图片描述

这里为了方便,暂且用有3个参数的构造方法即最后一个,其中第一个参数TextView即需要自定义模式的对象,第二个参数Pattern表示自己定义的用来匹配第一个参数TextView中内容的正则表达式,最后一个参数Scheme我理解为当点击自定义链接时跳转的界面

如:在布局文件中新增一个TextView并设置一些默认的内容,然后在代码如下通过如下方式设置自定义链接

Pattern pattern = Pattern.compile("abc://\\S*");
Linkify.addLinks(textView,pattern,"abc");

为了当点击自定义链接时点击能够响应,在这里新建了一个WebViewActivity类专门用来处理响应,但是有一点需要注意是需要在AndroidManifest清单文件中相应的activity节点下添加如下代码
这里写图片描述

效果如图:
这里写图片描述

当然,我们也可以通过这种方法实现上面所实现的拦截超链接的功能,这里就不再详细说明了

另外,当一个TextView即需要使用内置模式又需要使用自定义模式时必须先声明内置模式然后再声明自定义模式,并且经测试发现:不能在xml布局文件中通过autoLink属性来声明内置模式,否则自定义模式不起作用

xml代码

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="内置模式:拨打电话10086\n自定义链接:abc://baidu.com"
        android:layout_marginTop="10dp"/>

java代码


        textView = (TextView)findViewById(R.id.text);

        //多种模式
        Linkify.addLinks(textView,Linkify.PHONE_NUMBERS);
        Pattern pattern = Pattern.compile("abc://\\S*");
        Linkify.addLinks(textView, pattern, "abc");

效果:
这里写图片描述

借助SpannableString定制超链接的跳转

主要代码

 //借助SpannableString类实现超链接文字
        textView = (TextView)findViewById(R.id.text);
        textView.setText(getClickableSpan());
        //设置超链接可点击
        textView.setMovementMethod(LinkMovementMethod.getInstance());
/**
     * 获取可点击的SpannableString
     * @return
     */
    private SpannableString getClickableSpan() {
        SpannableString spannableString = new SpannableString("使用该软件,即表示您同意该软件的使用条款和隐私政策");
        //设置下划线文字
        spannableString.setSpan(new UnderlineSpan(), 16, 20, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        //设置文字的单击事件
        spannableString.setSpan(new ClickableSpan() {
            @Override
            public void onClick(View widget) {
                Toast.makeText(MainActivity.this,"使用条款", Toast.LENGTH_SHORT).show();
            }
        }, 16, 20, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        //设置文字的前景色
        spannableString.setSpan(new ForegroundColorSpan(Color.RED), 16, 20, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

        //设置下划线文字
        spannableString.setSpan(new UnderlineSpan(), 21, 25, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        //设置文字的单击事件
        spannableString.setSpan(new ClickableSpan() {
            @Override
            public void onClick(View widget) {
                Toast.makeText(MainActivity.this,"隐私政策",Toast.LENGTH_SHORT).show();
            }
        }, 21, 25, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        //设置文字的前景色
        spannableString.setSpan(new ForegroundColorSpan(Color.RED), 21, 25, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        return spannableString;
    }

效果
这里写图片描述

原文请戳这里

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值