How to set the part of the text view is clickable

后端 未结 20 1016
无人共我
无人共我 2020-11-22 01:29

I have the text \"Android is a Software stack\". In this text i want to set the \"stack\" text is clickable. in the sense if you click on t

相关标签:
20条回答
  • 2020-11-22 02:22

    i coded an example to solve your question in Kotlin.

    This is the Code:

        val completeText = getString(R.string.terms_description)
        val textToFind = getString(R.string.show_terms)
        val spannableString: Spannable = SpannableString(completeText)
        val startFocus = completeText.indexOf(textToFind)
        val endFocus = startFocus + textToFind.length
    
        spannableString.setSpan(object: ClickableSpan() {
            override fun onClick(p0: View) {
                showMessage()
            }
        }, startFocus, endFocus, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
        show_terms.text = spannableString
        show_terms.movementMethod = LinkMovementMethod.getInstance();
        show_terms.highlightColor = Color.TRANSPARENT;
    

    This is the XML

        <CheckBox
                android:id="@+id/check_agree_terms"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>
    
        <TextView
                android:id="@+id/show_terms"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textColorLink="@color/colorPrimary"
                android:layout_toEndOf="@id/check_agree_terms"/>
    

    This is how it looks

    enter image description here

    0 讨论(0)
  • 2020-11-22 02:25

    For bold,

    mySpannable.setSpan(new StyleSpan(Typeface.BOLD),termStart,termStop,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    
    0 讨论(0)
  • 2020-11-22 02:26

    The solutions provided are pretty decent. However, I generally use a more simple solution.

    Here is a linkify utility function

    /**
     * Method is used to Linkify words in a TextView
     *
     * @param textView TextView who's text you want to change
     * @param textToLink The text to turn into a link
     * @param url   The url you want to send the user to
     */
    fun linkify(textView: TextView, textToLink: String, url: String) {
        val pattern = Pattern.compile(textToLink)
        Linkify.addLinks(textView, pattern, url, { _, _, _ -> true })
        { _, _ -> "" }
    }
    

    Using this function is pretty simple. Here is an example

        // terms and privacy
        val tvTerms = findViewById<TextView>(R.id.tv_terms)
        val tvPrivacy = findViewById<TextView>(R.id.tv_privacy)
        Utils.linkify(tvTerms, resources.getString(R.string.terms),
                Constants.TERMS_URL)
        Utils.linkify(tvPrivacy, resources.getString(R.string.privacy),
                Constants.PRIVACY_URL)
    
    0 讨论(0)
  • 2020-11-22 02:29

    For those that are looking for a solution in Kotlin here is what worked for me:

    private fun setupTermsAndConditions() {
        val termsAndConditions = resources.getString(R.string.terms_and_conditions)
        val spannableString = SpannableString(termsAndConditions)
        val clickableSpan = object : ClickableSpan() {
            override fun onClick(widget: View) {
                if (checkForWifiAndMobileInternet()) {
                    // binding.viewModel!!.openTermsAndConditions()
                    showToast("Good, open the link!!!")
    
                } else {
                    showToast("Cannot open this file because of internet connection!")
                }
    
            }
    
            override fun updateDrawState(textPaint : TextPaint) {
                super.updateDrawState(textPaint)
                textPaint.color = resources.getColor(R.color.colorGrey)
                textPaint.isFakeBoldText = true
            }
        }
    
        spannableString.setSpan(clickableSpan, 34, 86, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
        binding.tvTermsAndConditions.text = spannableString
        binding.tvTermsAndConditions.movementMethod = LinkMovementMethod.getInstance()
        binding.tvTermsAndConditions.setHighlightColor(Color.TRANSPARENT);
    
    }
    
    0 讨论(0)
  • 2020-11-22 02:31

    My function for make multiple links inside TextView

    fun TextView.makeLinks(vararg links: Pair<String, View.OnClickListener>) {
        val spannableString = SpannableString(this.text)
        for (link in links) {
            val clickableSpan = object : ClickableSpan() {
    
                override fun updateDrawState(textPaint: TextPaint) {
                     // use this to change the link color
                     textPaint.color = textPaint.linkColor
                     // toggle below value to enable/disable
                     // the underline shown below the clickable text
                     textPaint.isUnderlineText = true
                }
    
                override fun onClick(view: View) {
                    Selection.setSelection((view as TextView).text as Spannable, 0)
                    view.invalidate()
                    link.second.onClick(view)
                }
            }
            val startIndexOfLink = this.text.toString().indexOf(link.first)
            spannableString.setSpan(clickableSpan, startIndexOfLink, startIndexOfLink + link.first.length,
                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
        }
        this.movementMethod = LinkMovementMethod.getInstance() // without LinkMovementMethod, link can not click
        this.setText(spannableString, TextView.BufferType.SPANNABLE)
    }
    

    USING

    my_text_view.makeLinks(
            Pair("Terms of Service", View.OnClickListener {
                Toast.makeText(applicationContext, "Terms of Service Clicked", Toast.LENGTH_SHORT).show()
            }),
            Pair("Privacy Policy", View.OnClickListener {
                Toast.makeText(applicationContext, "Privacy Policy Clicked", Toast.LENGTH_SHORT).show()
            }))
    

    XML

    <TextView
        android:id="@+id/my_text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Please accept Terms of Service and Privacy Policy"
        android:textColorHighlight="#f00" // background color when pressed
        android:textColorLink="#0f0"
        android:textSize="20sp" />
    

    DEMO

    Reference

    Solution for clear the link highlight selection follow https://stackoverflow.com/a/19445108/5381331

    0 讨论(0)
  • 2020-11-22 02:31

    more generic answer in kotlin

       fun setClickableText(view: TextView, firstSpan: String, secondSpan: String) {
        val context = view.context
        val builder = SpannableStringBuilder()
        val unClickableSpan = SpannableString(firstSpan)
        val span = SpannableString(" "+secondSpan)
    
        builder.append(unClickableSpan);
        val clickableSpan: ClickableSpan = object : ClickableSpan() {
            override fun onClick(textView: View) {
                val intent = Intent(context, HomeActivity::class.java)
             context.startActivity(intent)
            }
    
            override fun updateDrawState(ds: TextPaint) {
                super.updateDrawState(ds)
                ds.isUnderlineText = true
                ds.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.ITALIC));
            }
        }
        builder.append(span);
        builder.setSpan(clickableSpan, firstSpan.length, firstSpan.length+secondSpan.length+1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
    
        view.setText(builder,TextView.BufferType.SPANNABLE)
        view.setMovementMethod(LinkMovementMethod.getInstance());
    
    
    }
    
    0 讨论(0)
提交回复
热议问题