首页 > 技术文章 > Android TextView中实现点击文本超链接(无下划线)的封装类

zfyouxi 2014-10-08 16:22 原文

        android中有的时候须要在TextView上设置一些超链接,点击这些超链接时进行一些操作。比如新浪微博上的一些keyword,点击时会跳转到对应的页面。


      怎样实现我们就直接看源代码吧。

/**
 *
 *	created by Mr.Simple, Aug 21, 20141:51:40 PM.
 *	Copyright (c) 2014, hehonghui@umeng.com All Rights Reserved.
 *
 *                #####################################################
 *                #                                                   #
 *                #                       _oo0oo_                     #   
 *                #                      o8888888o                    #
 *                #                      88" . "88                    #
 *                #                      (| -_- |)                    #
 *                #                      0\  =  /0                    #   
 *                #                    ___/`---'\___                  #
 *                #                  .' \\|     |# '.                 #
 *                #                 / \\|||  :  |||# \                #
 *                #                / _||||| -:- |||||- \              #
 *                #               |   | \\\  -  #/ |   |              #
 *                #               | \_|  ''\---/''  |_/ |             #
 *                #               \  .-\__  '-'  ___/-. /             #
 *                #             ___'. .'  /--.--\  `. .'___           #
 *                #          ."" '<  `.___\_<|>_/___.' >' "".         #
 *                #         | | :  `- \`.;`\ _ /`;.`/ - ` : | |       #
 *                #         \  \ `_.   \_ __\ /__ _/   .-` /  /       #
 *                #     =====`-.____`.___ \_____/___.-`___.-'=====    #
 *                #                       `=---='                     #
 *                #     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   #
 *                #                                                   #
 *                #               佛祖保佑         永无BUG              #
 *                #                                                   #
 *                #####################################################
 */

package com.umeng.community.utils;

import android.content.Context;
import android.text.Html;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.TextPaint;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.text.style.URLSpan;
import android.widget.TextView;

/**
 * @author mrsimple
 */
public abstract class TopicSpanWrapper extends ClickableSpan {
    protected Context mContext;
    protected TextView mTextView;

    /**
     * @param context
     * @param tv
     */
    public TopicSpanWrapper(Context context, TextView tv) {
        mContext = context;
        mTextView = tv;
        updateClickSpan(tv);
    }

    /**
     * 更新Span
     * 
     * @param rv
     */
    public void updateClickSpan(TextView tv) {
        // 这里拼接超链接, 我在前后加了一个井号,可自行去除
        String htmlLinkText = "<a href='这里能够填写某个url'>#" + tv.getText().toString() + "#</a>";

        tv.setText(Html.fromHtml(htmlLinkText));
        tv.setMovementMethod(LinkMovementMethod.getInstance());
        CharSequence text = tv.getText();
        if (text instanceof Spannable) {
            int end = text.length();
            Spannable sp = (Spannable) tv.getText();
            URLSpan[] urls = sp.getSpans(0, end, URLSpan.class);
            SpannableStringBuilder style = new SpannableStringBuilder(text);
            style.clearSpans(); // should clear old spans
            for (URLSpan url : urls) {
                // 设置Span
                style.setSpan(this, sp.getSpanStart(url), sp.getSpanEnd(url),
                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
            tv.setText(style);
        }
    }

    @Override
    public void updateDrawState(TextPaint ds) {
        super.updateDrawState(ds);
        // 去掉超链接的下划线
        ds.setUnderlineText(false);
    }
}

使用演示样例 : 

public class UserInfoActivity extends FragmentActivity implements OnClickListener {

    FragmentManager mFragmentMan;
  

    private TextView mUserNameTv;

    /*
     * (non-Javadoc)
     * @see android.app.Activity#onCreate(android.os.Bundle)
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.umeng_comm_user_info);

        initUIComponents();
    }

    /**
     * 
     */
    private void initUIComponents() {
        mFragmentMan = getSupportFragmentManager();
        mPostedFragment = new PostedFragment();
        mFragmentMan
                .beginTransaction()
                .add(R.id.user_info_fragment_container, mPostedFragment,
                        PostedFragment.class.getSimpleName()).commit();

        // 布局就不给出了,总之user_name_tv是一个TextView
        mUserNameTv = (TextView) findViewById(R.id.user_name_tv);

        /**
         * 将TextView中的文本包装成可点击的超链接
         */
        new TopicSpanWrapper(this, mUserNameTv) {

            @Override
            public void onClick(View widget) {
                Toast.makeText(mContext, "点击了超链接文本", Toast.LENGTH_SHORT).show();
            }
        };

     
    }

}

效果如图 : 

  


点击以后 




图片中Toast的文字和代码的不一致,是由于文中写的与我demo中的文字不一样,直接忽略这个问题就可以。


推荐阅读