Android项目封装一个登录页隐私协议弹窗工具包(一)
在写andorid原生时, 登录页面一般会显示用户注册服务协议和隐私政策协议. 直接硬编码的话, 感觉不太优雅, 也不利于组件的移植.
例如:
所以想封装一个支持无限添加的各种协议的工具包. 代码如下:
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多个标签.例如下面的:
以上就是该工具包的所有代码, 以及如何使用.
可以修改
ProtocolEnum
类, 添加自己相应的枚举, 使其支持更多的标签
热门文章
- 「4月6日」最高速度22.9M/S,2025年Clash Nyanpasu每天更新免费节点订阅链接
- JDK内置锁深入探究
- 「3月13日」最高速度21M/S,2025年Clash Nyanpasu每天更新免费节点订阅链接
- 宠物用青霉素(宠物青霉素过敏吗)
- 制作猫粮狗粮的机器多少钱(制作猫狗粮的设备)
- 「3月21日」最高速度21.4M/S,2025年Clash Nyanpasu每天更新免费节点订阅链接
- 叫猫过来的手势视频(叫猫过来怎么说)
- 「4月1日」最高速度19.2M/S,2025年Clash Nyanpasu每天更新免费节点订阅链接
- 安泰宠物诊所电话地址查询(安泰养殖有限公司)
- 动物疫苗碰到人的皮肤有害吗会传染吗视频教程(动物打了疫苗的,伤了人怎么办)