androidxmlkotlin

Android Kotlin - making link in TextView clickable


In strings.xml I have the keyword

by_continuing_you_agree_terms_and_policy

the string

By continuing, you agree our Terms of Service and <a href="https://www.google.com">Privacy Policy</a>

This is the TextView:

<TextView
    android:id="@+id/createAccountTermsText"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:paddingTop="8dp"
    android:text="@string/by_continuing_you_agree_terms_and_policy"
    android:textColor="#A1A1A1" />

but nothing happens when I tap it.

Based on the "solutions" in other questions I added

    android:autoLink="web"
    android:linksClickable="true"

doesn't work either, so I added:

binding.createAccountTermsText.movementMethod = LinkMovementMethod.getInstance()

but that doesn't work either.


Solution

  • Alright this is the full solution:

        val text = getString(R.string.by_continuing_you_agree_terms_and_policy)
        val ss = SpannableString(text)
    
        val clickTerms: ClickableSpan = object : ClickableSpan() {
            override fun onClick(widget: View) {
                Log.d(tagg, "terms clicked")
                binding.createAccountTermsText.clearFocus()
            }
        }
    
        val clickPrivacy: ClickableSpan = object : ClickableSpan() {
            override fun onClick(widget: View) {
                Log.d(tagg, "privacy clicked")
                binding.createAccountTermsText.clearFocus()
            }
        }
        
        val hintColorOne = ForegroundColorSpan(Color.parseColor("#FF0000"))
        val hintColorTwo = ForegroundColorSpan(Color.parseColor("#FF0000"))
    
        ss.setSpan(hintColorOne, 29, 45, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
        ss.setSpan(hintColorTwo, 50, 64, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
    
        ss.setSpan(clickTerms, 29, 45, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
        ss.setSpan(clickPrivacy, 50, 64, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
    
        binding.createAccountTermsText.text = ss
        binding.createAccountTermsText.movementMethod = LinkMovementMethod.getInstance()
    

    the ints are standing for first/last characters, which means the color and click area is between them.

    Note 1: using hintColorOne and hintColorTwo instead of like hintColorOne for both spans is necessary, because using only one for both spans would make only the second span work. It's just plain happiness to develop android apps with all those surprises!

    Note 2: Using clickableSpan will disable the defined color and make use of the in the XML defined android:textColorLink="#FF0000" instead