安卓开发:记录一个用户协议和隐私政策的实现,富文本SpannableString以及富文本的点击事件

有一个需求,实现一个用户协议和隐私政策的实现,一个弹窗,一段文案,里面包含两个蓝色书名号文本,一个是《用户协议》,一个是《隐私政策》,这两个需要是蓝色文字,并且可以点击,简单记录一下实现过程,直接看代码吧:


    private fun showPrivacyPolicyDialog() {
    
    
        val builder: AlertDialog.Builder = AlertDialog.Builder(this)

        // 使用LayoutInflater加载自定义布局
        val inflater = layoutInflater
        val dialogView: View = inflater.inflate(R.layout.dialog_privacy_policy, null)
        builder.setView(dialogView)
        val dialog: AlertDialog = builder.create()
        val yinsi = dialogView.findViewById<TextView>(R.id.tv_yinsi)

        // 获取隐私政策文本
        val privacyPolicyText = getString(R.string.privacy_policy)

        // 找到所有书名号的起始位置和结束位置,并分别设置点击事件和蓝色样式
        var startIndex = 0
        var spannableString = SpannableString(privacyPolicyText)
        while (startIndex >= 0) {
    
    
            val startIndexTemp = privacyPolicyText.indexOf("《", startIndex)
            val endIndex = privacyPolicyText.indexOf("》", startIndexTemp) + 1
            startIndex = if (startIndexTemp >= 0 && endIndex > 0) {
    
    
                // 设置点击事件和蓝色样式
                val clickableSpan: ClickableSpan = object : ClickableSpan() {
    
    
                    override fun onClick(@NonNull widget: View) {
    
    
                        // 获取书名号的内容
                        val bookTitle =
                            privacyPolicyText.substring(startIndexTemp + 1, endIndex - 1)

                        // 在这里处理书名号点击事件,可以打开网页或者其他操作
                        openPrivacyPolicyLink(bookTitle)
                    }
                }
                spannableString.setSpan(
                    clickableSpan,
                    startIndexTemp,
                    endIndex,
                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                )
                spannableString.setSpan(
                    ForegroundColorSpan(resources.getColor(R.color.text_blue)),
                    startIndexTemp,
                    endIndex,
                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                )
                // 更新起始位置,继续查找下一个书名号
                endIndex
            } else {
    
    
                -1 // 找不到更多书名号,退出循环
            }
        }
        // 设置TextView的文本为SpannableString
        yinsi.append(spannableString)
        yinsi.setMovementMethod(LinkMovementMethod.getInstance())
        val btnAgree = dialogView.findViewById<MaterialButton>(R.id.btn_agree)
        btnAgree.setOnceClick {
    
    
            dialog.hide()
        }
        val btnNotAgree = dialogView.findViewById<TextView>(R.id.btn_not_agree)
        btnNotAgree.setOnceClick {
    
    
            AppManager.finishAllActivity()
//            android.os.Process.killProcess(android.os.Process.myPid())
            exitProcess(1)
        }
        dialog.show()
    }
    private fun openPrivacyPolicyLink(title:String) {
    
    
        // 在这里处理书名号点击事件,可以打开网页或者其他操作
        // 例如,打开隐私政策网页
        ToastUtils.showToast(title)
    }

上面这个showPrivacyPolicyDialog方法就是创建一个弹窗,弹窗内容是一个自定义的布局,稍后我会把布局内容也贴上,以方便弟弟们伸手拿。openPrivacyPolicyLink方法就是点击以后的跳转方法,点击了哪个可以用参数内容区分。
下面是布局:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:tools="http://schemas.android.com/tools"
    android:paddingHorizontal="@dimen/dp_16"
    android:orientation="vertical">

    <androidx.core.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginBottom="@dimen/dp_110"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toTopOf="@id/ll_btn">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintTop_toTopOf="parent">

            <TextView
                android:id="@+id/tv_title"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginHorizontal="@dimen/dp_12"
                android:layout_marginVertical="@dimen/dp_24"
                android:gravity="center"
                android:text="@string/yinsizhengce"
                android:textColor="@color/black_333333"
                android:textSize="22sp"
                android:textStyle="bold" />

            <TextView
                android:id="@+id/tv_yinsi"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginHorizontal="@dimen/dp_12"
                tools:text="@string/privacy_policy"
                android:textColor="@color/black_333333"
                android:textSize="16sp" />
        </LinearLayout>

    </androidx.core.widget.NestedScrollView>

    <LinearLayout
        android:id="@+id/ll_btn"
        android:layout_width="match_parent"
        android:layout_height="@dimen/dp_100"
        android:background="@color/white"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent">

        <com.google.android.material.button.MaterialButton
            android:id="@+id/btn_agree"
            style="@style/common_button"
            android:layout_alignParentBottom="true"
            android:layout_marginHorizontal="@dimen/dp_12"
            android:text="同意"
            app:cornerRadius="@dimen/dp_32" />

        <TextView
            android:id="@+id/btn_not_agree"
            style="@style/no_bg_button"
            android:layout_width="wrap_content"
            android:layout_gravity="center"
            android:layout_marginHorizontal="@dimen/dp_12"
            android:text="不同意,退出" />
    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

里面有一点就是布局用了style,如果你们的话,可以删掉这行,然后自己写必要属性和样式

猜你喜欢

转载自blog.csdn.net/Spy003/article/details/131757986
今日推荐