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

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


当前回答

我的功能使TextView内的多个链接 更新2020:现在这个函数能够支持多个相同的文本链接在1 TextView,但记得把链接在正确的顺序

fun TextView.makeLinks(vararg links: Pair<String, View.OnClickListener>) {
    val spannableString = SpannableString(this.text)
    var startIndexOfLink = -1
    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)
            }
        }
        startIndexOfLink = this.text.toString().indexOf(link.first, startIndexOfLink + 1)
//      if(startIndexOfLink == -1) continue // todo if you want to verify your texts contains links text
        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)
}

使用

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

参考

解决方案清除链接高亮选择遵循https://stackoverflow.com/a/19445108/5381331

其他回答

使用URLSpan类获取url

val spans: Array<URLSpan> = result.getSpans(0, result.length, URLSpan::class.java)

方法

fun TextView.createClickable(string: String, action:(String)->Unit ) {
      text = HtmlCompat.fromHtml(string, HtmlCompat.FROM_HTML_MODE_LEGACY)
      val result = SpannableString(text)
      val spans = result.getSpans(0, result.length, URLSpan::class.java)
      for (span in spans) {
          val link:Pair<String, View.OnClickListener> = Pair(span.url, View.OnClickListener {
              action(span.url)
          })
          val start = result.getSpanStart(span)
          val end = result.getSpanEnd(span)
          val flags = result.getSpanFlags(span)
          result.removeSpan(span)
          val clickableSpan: ClickableSpan = object : ClickableSpan() {
              override fun onClick(textView: View) {
                  textView.invalidate()
                  link.second.onClick(textView)
              }
              override fun updateDrawState(textPaint: TextPaint) {
                  super.updateDrawState(textPaint)
                  textPaint.isUnderlineText = false
              }
          }
          result.setSpan(clickableSpan, start, end, flags)
          this.movementMethod = LinkMovementMethod.getInstance()
          this.setText(result, TextView.BufferType.SPANNABLE)
      }
  }

Use

示例文本:Android是一个软件堆栈,它非常棒

包装你的可点击的文本内锚标签

比如:Android是一个软件<a href='https://example.com/stack'> Stack </a>和它' <a href='https://example.com/awesome'> Awesome </a>。

 val str = "Android is a Software <a href='https://example.com/stack'> Stack </a> and it' <a href='https://example.com/awesome'> Awesome </a>."

textView.createClickable(str) {
    when(it) {
        "https://example.com/stack"->{
  startActivity(Intent(this,StackActivity::class.java))
                  }
        "https://example.com/awesom"->{
            startActivity(Intent(this,AwesomeActivity::class.java))
        }
    }
}

你可以像本文中描述的那样使用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);

参考

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


}

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