处理点击隐私政策,后边空白区域触发了点击事件

2,459 阅读2分钟

本文已参与好文召集令活动,点击查看:后端、大前端双赛道投稿,2万元奖池等你挑战!

最近公司在用户登录界面要加《用户协议》以及《隐私政策》,话还没等产品说完,我就想到了用 SpannableString 做,说起来简单,当然,做起来也简单,之前做app都会有这种需求,这次字比较多,一行展示不完,如图1,2,不过这没关系,然后我就提给测试测了,过了会,刚要伸懒腰,测试过来说有问题,为啥点空白区域也会进隐私政策的界面,很纳闷,我测的时候没问题啊(原来是只点了字的,尴尬),那就改呗,于是踏上英雄的征途。 image.png 图1 image.png 图2

英雄的征途大致分为四个阶段

第一阶段:遇到问题;第二阶段:寻找问题; 第三阶段:解决问题;第四阶段:把这个解决问题方法分享给大家。

第一阶段:遇到问题

点击空白区域也能触发点击事件

第二阶段:寻找问题

通过SpannableString 虽然设置好了,但是还差点击事件的响应,如果不加下面这行代码,那么点击事件是没有用的,所以问题出现在了这,如下图: image.png 那就看源码吧,LinkMovementMethod类,点击事件肯定通过onTouchEvent方法实现,下图圈起来的,在特定的条件下会计算出错导致的,这里的特定条件有两种情况:

第一种:当你的TextView宽度设置为android:layout_width="wrap_content"并且存在换行时;

第二种:当你的TextView宽度设置为android:layout_width="match_parent"并且没有填满TextView时 image.png

第三阶段:解决问题

<string name="privacy_policy">《隐私政策》&#160;</string>

注意:因为加了空格,所以别忘了减1,如下图: image.png

第四阶段:把这个解决问题方法分享给大家

以下是全部代码:方便大家搬砖愉快。

  1. string里定义名字
    <string name="login_consent">登录注册即表明您已阅读并同意</string>
    <string name="user_service">《用户服务协议》&#160;</string>
    <string name="privacy_policy">《隐私政策》&#160;</string> 
    
  2. xml布局
 <TextView
            android:id="@+id/tv_agreement"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_marginLeft="16dp"
            android:layout_marginRight="16dp"
            android:layout_marginBottom="20dp"
            />
  1. 登录协议工具类
/**
 * @author Created by JasonYin
 * Description:协议工具类
 */
class LoginAgrementView(private val activity: Activity, private val tvArrgement: TextView) {
    /**
     * 用户协
     */
    fun useAgrement() {
        tvArrgement.text = activity.getString(R.string.login_consent)
        val clickString = SpannableString(activity.getString(R.string.user_service))
        clickString.setSpan(ForegroundColorSpan(Color.parseColor("#FFFFFF")), 0, clickString.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
        clickString.setSpan(object : ClickableSpan() {
            override fun onClick(widget: View) {
                Log.e("---> $", "用户协议")
            }

            override fun updateDrawState(ds: TextPaint) {
                super.updateDrawState(ds)
                ds.color=ContextCompat.getColor(activity, R.color.blue)
                ds.isUnderlineText = false
            }
        }, 0, clickString.length - 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
        tvArrgement.append(clickString)
        tvArrgement.append(SpannableString("和"))
        val clickStringPrivacy = SpannableString(activity.getString(R.string.privacy_policy))
        clickStringPrivacy.setSpan(object : ClickableSpan() {
            override fun onClick(widget: View) {
                Log.e("---> $", "隐私政策")
            }

            override fun updateDrawState(ds: TextPaint) {
                super.updateDrawState(ds)
                ds.color=ContextCompat.getColor(activity, R.color.blue)
                ds.isUnderlineText = false
            }
        }, 0, clickStringPrivacy.length - 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
        tvArrgement.append(clickStringPrivacy)
        //开始响应点击事件
        tvArrgement.movementMethod = LinkMovementMethod.getInstance()
    }

}
  1. 代码里引用
 LoginAgrementView(this, mBinding.tvProtocol).useAgrement()