我有文本“Android是一个软件堆栈”。在这个文本中,我想设置“堆栈”文本为可点击。所以,如果你点击它,它将重定向到一个新的活动(不在浏览器中)。

我试过了,但没有找到解决办法。


当前回答

这是一个kotlin扩展(不工作,如果文本重复)

textView.makeTextClickable(
    contentText = "Hello world",
    clickableText = "world",
    isBoldText = true,
    onClick = {
        openPageInBrowser(BuildConfig.PRIVACY_POLICY_URL)
    }
)



   internal fun TextView.makeTextClickable(
    contentText: String,
    clickableText: String,
    onClick: () -> Unit,
    isUnderlineText: Boolean = false,
    isBoldText: Boolean = false
) {
    val spannableString = SpannableString(contentText)

    val clickableSpan = object : ClickableSpan() {
        override fun onClick(widget: View) {
            onClick()
        }

        override fun updateDrawState(ds: TextPaint) {
            super.updateDrawState(ds)
            ds.isUnderlineText = isUnderlineText
            ds.isFakeBoldText = isBoldText
        }
    }

    val clickableTextStartIndex = text.indexOf(clickableText)
    val clickableTextEndIndex = clickableTextStartIndex + clickableText.length

    spannableString.setSpan(
        clickableSpan,
        clickableTextStartIndex,
        clickableTextEndIndex,
        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
    )

    this.text = spannableString
    this.movementMethod = LinkMovementMethod.getInstance()
}

其他回答

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());


}

它对文本的某些部分的可点击部分非常有帮助。

点是正则表达式中的一个特殊字符。如果你想要分隔圆点,需要将圆点转义为\\。而不是仅仅将"."传递给可扩展的文本方法。或者,也可以使用正则表达式[。在Java中通过一个点来分隔字符串。

大胆的,

mySpannable.setSpan(new StyleSpan(Typeface.BOLD),termStart,termStop,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

这里有一个Kotlin解决方案,与本地化工作得更好:

data class LinkedText(@StringRes val textRes: Int, val clickListener: View.OnClickListener? = null)

fun TextView.setPartiallyLinkedText(vararg texts: LinkedText) {
    this.text = texts.joinToString(" ") { context.getString(it.textRes) }
    val spannableString = SpannableString(this.text)
    var startIndexOfLink = -1
    texts.forEach { text ->
        val string = context.getString(text.textRes)
        if (text.clickListener != null) {
            val clickableSpan = object : ClickableSpan() {
                override fun updateDrawState(textPaint: TextPaint) {
                    textPaint.color = textPaint.linkColor
                    textPaint.isUnderlineText = true
                }
                override fun onClick(view: View) {
                    Selection.setSelection((view as TextView).text as Spannable, 0)
                    view.invalidate()
                    text.clickListener.onClick(view)
                }
            }
            startIndexOfLink = this.text.toString().indexOf(string, startIndexOfLink + 1)
            spannableString.setSpan(
                clickableSpan, startIndexOfLink, startIndexOfLink + string.length,
                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
            )
        }
    }
    this.movementMethod = LinkMovementMethod.getInstance()
    this.setText(spannableString, TextView.BufferType.SPANNABLE)
}

像这样使用它:

textView.setPartiallyLinkedText(
    LinkedText(R.string.not_linked_text),
    LinkedText(R.string.linked_text) {
        Toast.makeText(context, "You clicked", Toast.LENGTH_LONG).show()
    },
)

您可以使用示例代码。您希望了解关于ClickableSpan的详细信息。请检查这份文件

  SpannableString myString = new SpannableString("This is example");
            
            ClickableSpan clickableSpan = new ClickableSpan() {
                    @Override
                    public void onClick(View textView) {
                        ToastUtil.show(getContext(),"Clicked Smile ");
                    }
                };
        
        //For Click
         myString.setSpan(clickableSpan,startIndex,lastIndex,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        
        //For UnderLine
         myString.setSpan(new UnderlineSpan(),startIndex,lastIndex,0);
        
        //For Bold
        myString.setSpan(new StyleSpan(Typeface.BOLD),startIndex,lastIndex,0);
        
        //Finally you can set to textView. 
        
        TextView textView = (TextView) findViewById(R.id.txtSpan);
        textView.setText(myString);
        textView.setMovementMethod(LinkMovementMethod.getInstance());