Android development: record the implementation of a user agreement and privacy policy, rich text SpannableString and rich text click events

There is a need to implement a user agreement and privacy policy, a pop-up window, a piece of copywriting, which contains two blue book title texts, one is the "User Agreement" and the other is "Privacy Policy", these two needs are blue Color text, and can be clicked, simply record the implementation process, directly look at the code:


    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)
    }

The showPrivacyPolicyDialog method above is to create a pop-up window. The content of the pop-up window is a custom layout. I will paste the layout content later, so that brothers can reach for it. The openPrivacyPolicyLink method is the jump method after clicking. Which one is clicked can be distinguished by the parameter content.
Here is the layout:

<?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>

One thing in it is that the layout uses style, if you want, you can delete this line, and then write the necessary attributes and styles yourself

Guess you like

Origin blog.csdn.net/Spy003/article/details/131757986