支持Html渲染的TextView—LinkTextView

需求场景是这样的:
在Android中实现如下效果:
这里写图片描述
很多人都会说:So easy!交给h5去做,It’s not my bussiness!

好吧,我也好想说一句:H5你去做吧,It’s not my bussiness!
然并卵,产品需求说要做Android源生的,然后苦逼的事情就此开始了……

然后,思想步入正轨,开始思考这个需求的实现方式:
1.一个TextView控件,通过SpannableString的方式把“打开百度”字样拼接上去
必须承认,这是实现这种效果为数不多的方法之一,然而实现过程会略显复杂:
首先需要确定”打开百度”几个字符的位置,然后通过SpannableString拼接到TextView上去。

Finished!
Really ? It’s not finished!

需求分析并非如此!
将”打开百度”文字按照这个样式拼上去只是第一步,更重要的是你点击这个TextView能从浏览器中打开这个百度链接吗?

那有人就会说了,再获取到url通过浏览器打开就行了!
的确,这样是可以实现,但是拼接指定样式的字符已经是很复杂了,再获取URL打开链接会让实现方式更复杂一些,而且这些需求的实现过程都是在View层操作的,比如你在Activity中先获取到这个TextView,然后在通过SpannaleString 将字符拼接,然后再拿到URL去打开链接。

换句话说,如果有100个地方需要实现这种效果,就需要通过相同的逻辑复制100遍。

换个思路,能不能通过“改造”TextView自动实现这一过程?

必须可以。

然后第二种实现方式就来了。

2.通过Html.fromHtml的方式实现
也就是说,将这些文字用html的格式传递,然后TextView使用Html的方式实现效果!

那么我们真正需要的数据格式应该是这样的:

<font color="black" style="text-size:20;">
    周末加班很不爽有木有?!
</font>
<a href="http://www.baidu.com">
    <font color="#fe751a">
        打开百度
    </font>
</a>
<font color="black" >看会电影休息一下吧!</font>

1.通过Html的方式实现如图的效果

伪代码如下:

textView.setText(Html.fromHtml(htmlStr));

这个就不需要详细阐述了。
2.获取URL
这里,我们使用正则表达式来获取百度链接,代码如下:

//匹配URL的正则表达式
    private static final String REGEX_STRING = "(http|ftp|https):\\/\\/[\\w\\-_]" +
            "+(\\.[\\w\\-_]+)+([\\w\\-\\.,@?^=%&amp;:/~\\+#]*[\\w\\-\\@?^=%&amp;/~\\+#])?";

Pattern pattern = Pattern.compile(REGEX_STRING);
                Matcher matcher = pattern.matcher(htmlStr);
                if (matcher.find()) {
                    String hrefUrl = matcher.group();
                    System.out.println("html->"+hrefUrl);
                    }
                }

至此,关键的实现细节已结束。
剩下的就是对TextView的“改造了”,具体流程不再阐述,完整代码如下:

package com.example.myview;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.text.Html;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.widget.TextView;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/** * Created by WangChunLei on 16/3/19. * e-mail:[email protected] */
public class LinkTextView extends TextView {
    //匹配URL的正则表达式
    private static final String REGEX_STRING = "(http|ftp|https):\\/\\/[\\w\\-_]" +
            "+(\\.[\\w\\-_]+)+([\\w\\-\\.,@?^=%&amp;:/~\\+#]*[\\w\\-\\@?^=%&amp;/~\\+#])?";
    private String tmpStr = "";

    public LinkTextView(Context context) {
        super(context);
    }

    public LinkTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public LinkTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public void setText(CharSequence text, BufferType type) {
        tmpStr = text.toString();
        if (text.toString().contains("href")) {
            super.setText(Html.fromHtml(text.toString()), type);
        } else {
            super.setText(text, type);
        }
    }

    public void performTextClick(Context context) {
        try {
            CharSequence text = tmpStr;
            if (!TextUtils.isEmpty(text)) {
                Pattern pattern = Pattern.compile(REGEX_STRING);
                Matcher matcher = pattern.matcher(text);
                if (matcher.find()) {
                    String hrefUrl = matcher.group();
                    if (!TextUtils.isEmpty(hrefUrl)) {
                        Intent intent = new Intent();
                        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        intent.setAction("android.intent.action.VIEW");
                        Uri content_url = Uri.parse(hrefUrl);
                        intent.setData(content_url);
                        context.startActivity(intent);
                    }
                }
            }
        } catch (Exception e) {
        }
    }
}

你可能感兴趣的:(html,textview,fromHtml,LinkTextVi)