0
点赞
收藏
分享

微信扫一扫

全渠道营销利器!如何利用客户管理软件实现全渠道营销?

佛贝鲁先生 03-24 18:00 阅读 2

Android 带html标签文本添加自定义超链接跳转

第一步:在html文本中加入html超链接标签,并做个标识

<a href="privacy">查看用户隐私协议</a>
<a href="important">查看重要声明</a>

这里我们增加了两个超链接,href的属性值主要用于标记要跳转到哪个APP界面,后面代码处理时会需要根据这个做不同处理

第二步:自定义一个可点击的文本块ClickableSpan

这里主要做了一个简单的封装,关键点在于重写ClickableSpanonCLick方法,它的updateDrawState方法中则可以修改超链接的一些属性,比如字体颜色,下划线等

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.text.TextPaint;
import android.text.TextUtils;
import android.text.style.ClickableSpan;
import android.view.View;

import androidx.annotation.ColorRes;
import androidx.annotation.NonNull;

public class ClickableSpanBuilder {

    private View.OnClickListener mListener;//点击事件
    private String mUrl;//要打开的网址
    private int mLinkColorRes;//超链接颜色
    Context mContext;

    public ClickableSpanBuilder(Context context) {
        this.mContext = context.getApplicationContext();
        mLinkColorRes = context.getColor(R.color.common_link_color);//超链接默认字体颜色
    }

    public ClickableSpanBuilder setClickListener(View.OnClickListener listener) {
        this.mListener = listener;
        return this;
    }

    public ClickableSpanBuilder setUrl(String url) {
        this.mUrl = url;
        return this;
    }

    public ClickableSpanBuilder setLinkColor(@ColorRes int colorRes) {
        this.mLinkColorRes = mContext.getColor(colorRes);;
        return this;
    }

    public ClickableSpan build() {
        return new CustomClickableSpan(mContext, mListener, mUrl, mLinkColorRes);
    }

    private static class CustomClickableSpan extends ClickableSpan {
        private View.OnClickListener mListener;//点击事件
        private String mUrl;//要打开的网址
        private Context mContext;
        private int mLinkColorRes;//超链接颜色

        public CustomClickableSpan(Context context, View.OnClickListener mListener, String mUrl, int linkColorRes) {
            this.mContext = context;
            this.mListener = mListener;
            this.mUrl = mUrl;
            this.mLinkColorRes = linkColorRes;
        }

        @Override
        public void onClick(@NonNull View widget) {
            if (mListener != null) {//处理点击事件
                mListener.onClick(null);
            } else if (!TextUtils.isEmpty(mUrl)) {//如果没有设置,则看是否有设置url
                if (mContext != null) {//有的话则使用系统浏览器跳转
                    mContext.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(mUrl)));
                }
            }
        }

        @Override
        public void updateDrawState(@NonNull TextPaint ds) {
            super.updateDrawState(ds);
            ds.setUnderlineText(true);//设置需要下划线
            ds.setColor(mLinkColorRes);//设置超链接字体颜色
        }
    }
}

第三步:封装一个工具类,实现处理带html标签的纯文本

工具类中封装了两个方法:

  • handleContentLink 处理带html标签的文本中所有超链接
    • Spanned sourceContent 这个就是通过Html.fromHtml解析html后返回的文本内容,其实解析之后html中的<a>会被解析成URLSpan对象进行封装
    • 通过SpannedgetSpans方法可以获取到所有的URLSpan对象,getSpanStart(URLSpan)getSpanEnd(URLSpan)可以获取指定Span标签的起始位置和结束位置,也就是<a>xxxxx</a>包括住的这部分内容前后位置
    • 通过URLSpan对象的getURL()方法就可以获取到我们在html中<a>标签的href属性值,用于区分该超链接要跳转到哪里
    • 还需要创建一个新的Spanned对象来保存我们修改后的文本内容,这里我们使用继承于SpannedSpannableStringBuilder,因为它有个clearSpans()方法可以将之前文本中所有旧的的URLSpan对象清除;如果不清楚旧的,直接添加新的会导致无法点击跳转
    • 通过上一步骤封装的ClickableSpanBuilder类创建可以自定义跳转逻辑的ClickableSpan对象
    • 通过SpannableStringBuilder.setSpan方法给指定范围的文本设置超链接点击事件
  • getClickableLink 返回一个可以点击的超链接文本
    • 用于普通String文本后面需要拼接一个超链接文本Spanned的场景
    • String文本和Spanned超链接文本不能直接拼接到一起
    • 需要调用TextViewappend(Spanned)方法将后面超链接文本拼接进去
import android.content.Context;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.style.ClickableSpan;
import android.text.style.URLSpan;
import android.util.Log;
import android.view.View;

public class LinkUtils {
    private static final String TAG = "LinkUtils";

    /**
     * 处理带html标签的文本中所有超链接
     * @param context
     * @param sourceContent
     * @return
     */
    public static Spanned handleContentLink(Context context, Spanned sourceContent) {
        SpannableStringBuilder tmp = new SpannableStringBuilder(sourceContent);
        tmp.clearSpans();//这里必须要清除旧的Span
        URLSpan[] urls = sourceContent.getSpans(0, sourceContent.length(), URLSpan.class);//获取所有的超链接标签<a>
        for (URLSpan urlSpan : urls) {
            Log.i(TAG, "url:" + urlSpan.getURL());
            if ("privacy".equals(urlSpan.getURL())) {
                ClickableSpan clickableSpan = new ClickableSpanBuilder(context)
                        .setLinkColor(R.color.common_content_text_color)
                        .setClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                //点击跳转用户隐私协议
                            }
                        }).build();
                tmp.setSpan(clickableSpan, sourceContent.getSpanStart(urlSpan), sourceContent.getSpanEnd(urlSpan), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            } else if ("important".equals(urlSpan.getURL())) {
                ClickableSpan clickableSpan = new ClickableSpanBuilder(context)
                        .setLinkColor(R.color.common_content_text_color)
                        .setClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                //点击跳转重要声明
                            }
                        }).build();
                tmp.setSpan(clickableSpan, sourceContent.getSpanStart(urlSpan), sourceContent.getSpanEnd(urlSpan), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
        }
        return tmp;
    }

    /**
     * 返回一个可以点击的超链接文本
     * @param context
     * @param linkText 超链接文本内容
     * @param listener 点击事件
     * @return
     */
    public static Spanned getClickableLink(Context context, String linkText, View.OnClickListener listener) {
        SpannableString linkSpan = new SpannableString(linkText);
        ClickableSpan clickableSpan = new ClickableSpanBuilder(context)
                .setClickListener(listener)
                .build();
        linkSpan.setSpan(clickableSpan, 0, linkSpan.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        return linkSpan;
    }
}

第四步:项目中的使用

  • 批量处理html文本中超链接用法:
Spanned htmlContent = Html.fromHtml("<a href=\"privacy\">查看用户隐私协议</a><a href=\"important\">查看重要声明</a>");

contentTextView.setText(LinkUtils.handleContentLink(this, htmlContent));
  • 纯文本拼接超链接文本用法:
Spanned linkSpan = LinkUtils.getClickableLink(this, "隐私和条款"
                    , new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            //自定义点击跳转
                        }
                    });
String content = "点击查看 ";
textView.setText(content);
textView.append((linkSpan));
举报

相关推荐

0 条评论