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

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


当前回答

对于kotlin使用这个扩展

fun TextView.makeLinks(vararg links: Pair<String, View.OnClickListener>) {
val spannableString = SpannableString(this.text)
for (link in links) {
    val clickableSpan = object : ClickableSpan() {
        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
    )
    spannableString.setSpan(
        ForegroundColorSpan(Color.parseColor("#46C2CC")),
        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)

}

像这样调用它

binding.agreeText.makeLinks(Pair(getString(R.string.terms_conditionsClick),View.OnClickListener {
        startActivity(TermsAndConditionActivity.getIntent(this))
    }))

其他回答

这是java爱好者的Boom Check:D 我们可以根据自己的需要进行修改:

List<Pair<String, View.OnClickListener>> pairsList = new ArrayList<>();

        pairsList.add(new Pair<>("38,50", v -> {
            Intent intent = new Intent(SignUpActivity.this, WebActivity.class);
            intent.putExtra("which", "tos");
            startActivity(intent);
        }));

        pairsList.add(new Pair<>("81,95", v -> {
            Intent intent = new Intent(SignUpActivity.this, WebActivity.class);
            intent.putExtra("which", "policy");
            startActivity(intent);
        }));

        makeLinks(pairsList); // Method calling


private void makeLinks(List<Pair<String, View.OnClickListener>> pairsList) {

        SpannableString ss = new SpannableString(By signing up, I’m agree to PAKRISM’s Terms of Use and confirms that I have read Privacy Policy);

        for (Pair<String, View.OnClickListener> pair : pairsList) {

            ClickableSpan clickableSpan = new ClickableSpan() {
                @Override
                public void onClick(View textView) {
                    //Toast.makeText(MyApplication.getAppContext(), "Clicked!", Toast.LENGTH_SHORT).show();
                    pair.second.onClick(textView);
                }

                @Override
                public void updateDrawState(TextPaint ds) {

                    ds.linkColor = ContextCompat.getColor(SignUpActivity.this, R.color.primary_main);
                    ds.setUnderlineText(true);

                    super.updateDrawState(ds);
                }
            };

            String[] indexes = pair.first.split(",");
            ss.setSpan(clickableSpan, Integer.parseInt(indexes[0]), Integer.parseInt(indexes[1]), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
        
        TextView tv = findViewById(R.id.txtView);
        tv.setText(ss);
        tv.setMovementMethod(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());


}

你可以像本文中描述的那样使用ClickableSpan

示例代码:

TextView myTextView = new TextView(this);
String myString = "Some text [clickable]";
int i1 = myString.indexOf("[");
int i2 = myString.indexOf("]");
myTextView.setMovementMethod(LinkMovementMethod.getInstance());
myTextView.setText(myString, BufferType.SPANNABLE);
Spannable mySpannable = (Spannable)myTextView.getText();
ClickableSpan myClickableSpan = new ClickableSpan() {
   @Override
   public void onClick(View widget) { /* do something */ }
};
mySpannable.setSpan(myClickableSpan, i1, i2 + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

参考

android.text.style.ClickableSpan可以解决你的问题。

SpannableString ss = new SpannableString("Android is a Software stack");
ClickableSpan clickableSpan = new ClickableSpan() {
    @Override
    public void onClick(View textView) {
        startActivity(new Intent(MyActivity.this, NextActivity.class));
    }
    @Override
    public void updateDrawState(TextPaint ds) {
        super.updateDrawState(ds);
        ds.setUnderlineText(false);
    }
};
ss.setSpan(clickableSpan, 22, 27, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

TextView textView = (TextView) findViewById(R.id.hello);
textView.setText(ss);
textView.setMovementMethod(LinkMovementMethod.getInstance());
textView.setHighlightColor(Color.TRANSPARENT);

在XML:

<TextView 
  ...
  android:textColorLink="@drawable/your_selector"
/>

提供的解决方案相当不错。然而,我通常使用更简单的解决方案。

这是一个linkify效用函数

/**
 * 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 })
    { _, _ -> "" }
}

使用这个函数非常简单。这里有一个例子

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