美文网首页
Android登录注册用户协议、隐私协议解决方案

Android登录注册用户协议、隐私协议解决方案

作者: 买辣条也想用券 | 来源:发表于2019-11-29 16:08 被阅读0次

    项目忙先看效果和上代码


    Video_20191129_043102_562.gif
    /**
     * 用户注册协议、用户隐私协议条款控件
     *
     * @author With You
     * @version 5.0.0
     * @date 2019/11/29 10:49
     * @email 1713397546@qq.com
     * @description
     */
    public class UrAgreementTextView extends AppCompatTextView {
    
        private final static String AgreementHintTag = "AgreementHintTag";
    
        private SpannableString spannableString = null;
        /**
         * 协议全内容
         */
        private String agreementContext = "我已阅读并同意《注册服务协议》,《用户隐私协议》与《风险揭示书》";
        /**
         * 协议提示文本
         */
        private String agreementHintText = "我已阅读并同意";
        /***
         * 协议内容
         */
        private CharSequence[] agreements = new String[]{"《注册服务协议》", "《用户隐私协议》", "《风险揭示书》"};
    
        /**
         * 协议全内容字体颜色
         */
        private int agreementContextColor;
        /**
         * 协议提示文本颜色
         */
        private int agreementHintColor;
        /**
         * 协议字体颜色
         */
        private int agreementsColor;
    
        private boolean isChecked = false;
        private Drawable agreementCheckDrawable;
        private Drawable agreementUnCheckDrawable;
    
        public UrAgreementTextView(Context context) {
            super(context);
        }
    
        public UrAgreementTextView(Context context, AttributeSet attrs) {
            super(context, attrs);
            initView(context, attrs);
        }
    
        public UrAgreementTextView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            initView(context, attrs);
        }
    
        private void initView(Context context, AttributeSet attrs) {
            TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.UrAgreementTextView);
            String agreementContext = typedArray.getString(R.styleable.UrAgreementTextView_agreementContext);
            String agreementHintText = typedArray.getString(R.styleable.UrAgreementTextView_agreementHintText);
            CharSequence[] agreements = typedArray.getTextArray(R.styleable.UrAgreementTextView_agreementsId);
            agreementContextColor = typedArray.getColor(R.styleable.UrAgreementTextView_agreementContextColor, 0xFF000000);
            agreementHintColor = typedArray.getColor(R.styleable.UrAgreementTextView_agreementHintColor, 0xFF000000);
            agreementsColor = typedArray.getColor(R.styleable.UrAgreementTextView_agreementsColor, 0xFFFF0000);
            isChecked = typedArray.getBoolean(R.styleable.UrAgreementTextView_isChecked, false);
            agreementCheckDrawable = typedArray.getDrawable(R.styleable.UrAgreementTextView_agreementCheckedId);
            agreementUnCheckDrawable = typedArray.getDrawable(R.styleable.UrAgreementTextView_agreementUnCheckedId);
            typedArray.recycle();
            if (!TextUtils.isEmpty(agreementContext))
                this.agreementContext = agreementContext;
            if (!TextUtils.isEmpty(agreementHintText))
                this.agreementHintText = agreementHintText;
            if (agreements != null) {
                for (int i = 0; i < agreements.length; i++) {
                    this.agreements[i] = agreements[i].toString();
                }
            }
            this.setHighlightColor(getResources().getColor(android.R.color.transparent));
            spannableString = new SpannableString(agreementContext);
            setDrawable(isChecked ? agreementCheckDrawable : agreementUnCheckDrawable);
            setAgreement();
        }
    
        /**
         * 设置勾选按钮图片
         *
         * @param drawable
         */
        private void setDrawable(Drawable drawable) {
            if (drawable != null) {
                drawable.setBounds(0, 0, dip2px(14), dip2px(14));
                spannableString.setSpan(new UrImageSpan(drawable), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
            setText(spannableString);
        }
    
        /**
         * 设置协议内容
         */
        public void setAgreement() {
            //设置协议显示效果
            for (int i = 0; i < agreements.length; i++) {
                CharSequence agreement = agreements[i];
                int firstIndex = agreementContext.indexOf(agreement.toString());
                int lastIndex = firstIndex + agreement.length();
                spannableString.setSpan(new MyClickableSpan(String.valueOf(i), agreement.toString(), agreementsColor),
                        firstIndex, lastIndex, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
            }
            //设置协议提示文本显示及点击效果
            int firstHintIndex = agreementContext.indexOf(agreementHintText);
            int lastHintIndex = firstHintIndex + agreementHintText.length();
            spannableString.setSpan(new MyClickableSpan(AgreementHintTag, agreementHintText, agreementHintColor),
                    firstHintIndex, lastHintIndex, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
            setText(spannableString);
            setMovementMethod(LinkMovementMethod.getInstance());
        }
    
        private class MyClickableSpan extends ClickableSpan {
            private String tag;
            private String agreement;
            private int color;
    
            public MyClickableSpan(String tag, String agreement, int color) {
                this.tag = tag;
                this.agreement = agreement;
                this.color = color;
            }
    
            @Override
            public void onClick(View widget) {
               if (tag.equals(AgreementHintTag)) //当点击同意协议时,勾选按钮
                {
                    setDrawable(!isChecked ? agreementCheckDrawable : agreementUnCheckDrawable);
                    isChecked = !isChecked;
                }
                if (agreementClickListener != null)
                    agreementClickListener.clickListener(tag, agreement, isChecked);
            }
    
            @Override
            public void updateDrawState(TextPaint ds) {
                ds.setColor(color);
                ds.setUnderlineText(false);
            }
        }
    
        private OnAgreementClickListener agreementClickListener;
    
        public void setAgreementClickListener(OnAgreementClickListener agreementClickListener) {
            this.agreementClickListener = agreementClickListener;
        }
    
        public interface OnAgreementClickListener {
            /**
             * @param tag
             * @param clickText 点击的文本
             * @param isCheck   协议是否勾选
             */
            void clickListener(String tag, String clickText, boolean isCheck);
    
        }
    
        /**
         * 将dip或dp值转换为px值,保证尺寸大小不变
         *
         * @param dipValue
         * @param dipValue (DisplayMetrics类中属性density)
         * @return
         */
        public int dip2px(float dipValue) {
            final float scale = getResources().getDisplayMetrics().density;
            return (int) (dipValue * scale + 0.5f);
        }
    }
    
    

    自定义ImageSpan实现TextView中文图混排时文图的居中对齐

    
    /**
     * 自定义ImageSpan实现TextView中文图混排时文图的居中对齐
     *
     * @author With You
     * @version 5.0.0
     * @date 2019/11/29 14:47
     * @email 1713397546@qq.com
     * @description
     */
    public class UrImageSpan extends ImageSpan {
    
        public UrImageSpan(Context context, Bitmap bitmap) {
            super(context, bitmap);
        }
    
        public UrImageSpan(Context context, Bitmap bitmap, int verticalAlignment) {
            super(context, bitmap, verticalAlignment);
        }
    
        public UrImageSpan(Drawable drawable) {
            super(drawable);
        }
    
        @Override
        public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {
            try {
                Drawable d = getDrawable();
                Rect rect = d.getBounds();
                if (fm != null) {
                    Paint.FontMetricsInt fmPaint = paint.getFontMetricsInt();
                    int fontHeight = fmPaint.bottom - fmPaint.top;
                    int drHeight = rect.bottom - rect.top;
                    int top = drHeight / 2 - fontHeight / 4;
                    int bottom = drHeight / 2 + fontHeight / 4;
                    fm.ascent = -bottom;
                    fm.top = -bottom;
                    fm.bottom = top;
                    fm.descent = top;
                }
                return rect.right;
            } catch (Exception e) {
                return 20;
            }
        }
    
        @Override
        public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
            try {
                Drawable d = getDrawable();
                canvas.save();
                int transY = 0;
                transY = ((bottom - top) - d.getBounds().bottom) / 2 + top;
                canvas.translate(x, transY);
                d.draw(canvas);
                canvas.restore();
            } catch (Exception e) {
            }
        }
    }
    

    attrs.xml 文件

    <declare-styleable name="UrAgreementTextView">
            <attr name="agreementContext" format="string" />
            <attr name="agreementHintText" format="string" />
            <attr name="agreementsId" format="integer|reference" />
            <attr name="agreementContextColor" format="color|reference" />
            <attr name="agreementHintColor" format="color|reference" />
            <attr name="agreementsColor" format="color|reference" />
            <attr name="isChecked" format="boolean" />
            <attr name="agreementCheckedId" format="reference" />
            <attr name="agreementUnCheckedId" format="reference" />
       </declare-styleable>
    

    xml页面布局中的使用

    <com.xx.xx.xx.UrAgreementTextView
            android:id="@+id/tv_agreement"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:lineSpacingMultiplier="1.2"
            android:padding="14dp"
            android:textSize="@dimen/Assign_style_textSize14"
            app:agreementCheckedId="@drawable/check_icon"
            app:agreementContext="@string/agreement"
            app:agreementContextColor="@color/text_color_666"
            app:agreementHintColor="@color/text_color_666"
            app:agreementUnCheckedId="@drawable/check_false"
            app:agreementsColor="@color/blue"
            app:agreementsId="@array/agreements"
            app:isChecked="false" />
    

    事件监听

      mTvAgreement.setAgreementClickListener((tag, clickText, isChecked) -> {
                UrUIToast.showText(mContext, clickText + isChecked);
            });
    

    相关文章

      网友评论

          本文标题:Android登录注册用户协议、隐私协议解决方案

          本文链接:https://www.haomeiwen.com/subject/injgwctx.html