Android项目封装一个登录页隐私协议弹窗工具包(一)

2023年6月18日10:09:38

Android项目封装一个登录页隐私协议弹窗工具包(一)

在写andorid原生时, 登录页面一般会显示用户注册服务协议和隐私政策协议. 直接硬编码的话, 感觉不太优雅, 也不利于组件的移植.
例如:
Android项目封装一个登录页隐私协议弹窗工具包(一)
所以想封装一个支持无限添加的各种协议的工具包. 代码如下:

import android.content.Context;
import android.graphics.Color;
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.ForegroundColorSpan;
import android.view.View;
import android.widget.TextView;

import androidx.annotation.NonNull;

import java.util.LinkedList;

/**
 * 首页隐私政策信息弹窗工具包
 */
public class PrivateProtocolUtil {


    public static void showDialog(Context context, TextView textView, String baseText, LinkedList<PrivateProtocolInfo> protocolInfos) {
        // 要求必须大于0
        if (protocolInfos == null || protocolInfos.size() <= 0) {
            throw new IndexOutOfBoundsException("协议关键字列表不能为空");
        }
        // 对显示的文案进行组装,支持无限拼接,未注册手机登录将自动生成账号,且代表您已阅读并同意《xxx注册服务协议》和《xxx隐私政策》
        StringBuilder valueTextBuilder = new StringBuilder(baseText);
        for (int i = 0; i < protocolInfos.size(); i++) {
            valueTextBuilder.append(protocolInfos.get(i).getValueText());
            if (i < protocolInfos.size() - 1) {
                valueTextBuilder.append("和");
            }
        }
        // 设置指定位置的文字为可点击的,并修改文字颜色
        String valueText = valueTextBuilder.toString();
        SpannableStringBuilder style = new SpannableStringBuilder(valueText);
        int baseTextLength = baseText.length();
        style.setSpan(new ForegroundColorSpan(Color.BLACK), 0, baseTextLength - 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        for (int i = 0; i < protocolInfos.size(); i++) {
            int itemLength = protocolInfos.get(i).getValueText().length();
            int temLength = baseTextLength + itemLength;
            if (i == 0) {
                style.setSpan(new CliclSpan(context, Color.parseColor(protocolInfos.get(i).getColor()), protocolInfos.get(i).getFlag(), protocolInfos.get(i).getOnTipItemClickListener()), baseTextLength, temLength, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            } else {
                temLength++;
                style.setSpan(new CliclSpan(context, Color.parseColor(protocolInfos.get(i).getColor()), protocolInfos.get(i).getFlag(), protocolInfos.get(i).getOnTipItemClickListener()), ++baseTextLength, temLength, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
            baseTextLength = temLength;
        }
        textView.setText(style);
        // 设置点击后的背景颜色为透明色
        textView.setHighlightColor(Color.TRANSPARENT);
        // 为指定字符设置链接属性,并激活链接
        textView.setMovementMethod(LinkMovementMethod.getInstance());

    }


    public static class PrivateProtocolInfo {
        // 文案内容
        private String valueText;
        // 标识符,在回调中区分,会返回
        private ProtocolEnum flag;
        // 文案内容的颜色
        private String color;
        // 回调监听
        private OnTipItemClickListener onTipItemClickListener;

        public PrivateProtocolInfo(String valueText, ProtocolEnum flag, String color, OnTipItemClickListener onTipItemClickListener) {
            this.valueText = valueText;
            this.flag = flag;
            this.color = color;
            this.onTipItemClickListener = onTipItemClickListener;
        }

        public String getValueText() {
            return valueText;
        }

        public void setValueText(String valueText) {
            this.valueText = valueText;
        }

        public ProtocolEnum getFlag() {
            return flag;
        }

        public void setFlag(ProtocolEnum flag) {
            this.flag = flag;
        }

        public String getColor() {
            return color;
        }

        public void setColor(String color) {
            this.color = color;
        }

        public OnTipItemClickListener getOnTipItemClickListener() {
            return onTipItemClickListener;
        }

        public void setOnTipItemClickListener(OnTipItemClickListener onTipItemClickListener) {
            this.onTipItemClickListener = onTipItemClickListener;
        }
    }

    public enum ProtocolEnum {
        USER_PROTOCOL,
        PRIVATE_PROTOCOL;
    }

    public interface OnTipItemClickListener {

        // 协议点击事件
        void itemClick(ProtocolEnum protocolEnum);
    }


    private static class CliclSpan extends ClickableSpan {
        private ProtocolEnum protocolEnum;
        private OnTipItemClickListener onTipItemClickListener;
        private int color;
        private Context context;

        public CliclSpan(Context context, int color, ProtocolEnum protocolEnum, OnTipItemClickListener onTipItemClickListener) {
            this.context = context;
            this.color = color;
            this.protocolEnum = protocolEnum;
            this.onTipItemClickListener = onTipItemClickListener;
        }

        @Override
        public void onClick(@NonNull View widget) {
            if (onTipItemClickListener == null) {
                return;
            }
            onTipItemClickListener.itemClick(protocolEnum);
        }

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

上面封装的就是一个util包, 它支持理论上支持设置无限多个协议标签. 具体的逻辑请看代码中的注释.

下面展示如何使用, 代码如下:

// 用户注册协议
PrivateProtocolUtil.PrivateProtocolInfo userProtocolInfo = new PrivateProtocolUtil.PrivateProtocolInfo("《xxx注册服务协议》", PrivateProtocolUtil.ProtocolEnum.USER_PROTOCOL, "#00be32", new PrivateProtocolUtil.OnTipItemClickListener() {
    @Override
    public void itemClick(PrivateProtocolUtil.ProtocolEnum protocolEnum) {
        if (PrivateProtocolUtil.ProtocolEnum.USER_PROTOCOL.equals(protocolEnum)) {
            // 进行用户注册的协议弹出
        }
    }
});
// 隐私政策协议
PrivateProtocolUtil.PrivateProtocolInfo privateProtocolInfo = new PrivateProtocolUtil.PrivateProtocolInfo("《xxx隐私政策》", PrivateProtocolUtil.ProtocolEnum.PRIVATE_PROTOCOL, "#00be32", new PrivateProtocolUtil.OnTipItemClickListener() {
    @Override
    public void itemClick(PrivateProtocolUtil.ProtocolEnum protocolEnum) {
        if (PrivateProtocolUtil.ProtocolEnum.PRIVATE_PROTOCOL.equals(protocolEnum)) {
            // 进行隐私政策的协议弹出
        }
    }
});
LinkedList<PrivateProtocolUtil.PrivateProtocolInfo> linkedList = new LinkedList<>();
linkedList.add(userProtocolInfo);
linkedList.add(privateProtocolInfo);
PrivateProtocolUtil.showDialog(LoginActivity.this, tvAgreement, "未注册手机登录将自动生成账号,且代表您已阅读并同意", linkedList);

以上就是工具包的使用方法, 可以看到,传入的是一个list, 所以可以设置n多个标签.例如下面的:
Android项目封装一个登录页隐私协议弹窗工具包(一)

以上就是该工具包的所有代码, 以及如何使用.

可以修改ProtocolEnum 类, 添加自己相应的枚举, 使其支持更多的标签

  • 作者:HUWD
  • 原文链接:https://blog.csdn.net/weixin_45089791/article/details/127210404
    更新时间:2023年6月18日10:09:38 ,共 5093 字。