我有以下TextView定义:

<TextView 
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" android:text="@string/txtCredits"
    android:autoLink="web" android:id="@+id/infoTxtCredits"
    android:layout_centerInParent="true"
    android:linksClickable="true"/>

其中@string/txtCredits是一个字符串资源,包含<a href="some site">链接文本</a>。

Android正在突出显示TextView中的链接,但它们不响应单击。我做错了什么?我必须在我的活动中为TextView设置一个onClickListener像这样简单吗?

它看起来和我定义字符串资源的方式有关。

这行不通:

<string name="txtCredits"><a href="http://www.google.com">Google</a></string>

但这确实是:

<string name="txtCredits">www.google.com</string>

这是一个遗憾,因为我宁愿显示一个文本链接,而不是显示完整的URL。


当前回答

我只使用android:autoLink=“web”,它工作得很好。单击该链接将打开浏览器并显示正确的页面。

我能猜到的一件事是,其他一些视图在链接的上方。透明的内容填充整个父元素,但不显示链接上方的任何内容。在这种情况下,点击指向这个视图而不是链接。

其他回答

我并不是要把它打得死死的,但下面是在Linkfy等人的被窝里发生的事情。您将注意到setText()接受CharSequence。Linkify等将字符串转换为span,并添加span。Spannable间接继承CharSequence,就像String一样,所以它与setText()一起工作。使用Spannables,你可以混合和匹配跨度,做各种有趣的事情。这里有一个简单的例子。

val textView = findViewById<TextView>(R.id.myTextView)
val span = SpannableStringBuilder(getString(R.string.linkText))
textView [0, textView .length] = URLSpan("https://myWebiste.com/")
textView.text = span
textView.movementMethod = LinkMovementMethod.getInstance()

需要注意的是,Kotlin语法非常流畅,但它混淆了Spannable.setSpan()调用,这就是魔术发生的地方。

我只使用android:autoLink=“web”,它工作得很好。单击该链接将打开浏览器并显示正确的页面。

我能猜到的一件事是,其他一些视图在链接的上方。透明的内容填充整个父元素,但不显示链接上方的任何内容。在这种情况下,点击指向这个视图而不是链接。

你可以简单地添加链接到你的TextView与Android的Linkify库。

添加到你的strings.xml

<string name="text_legal_notice">By continuing, you confirm that you have read, understood and agreed to our %1$s and %2$s.</string>
<string name="text_terms_conditions">Terms &amp; Conditions</string>
<string name="text_privacy_policy">Privacy Policy</string>

加入到你的活动中

final String termsConditionsText = getString(R.string.text_terms_conditions);
final String privacyPolicyText = getString(R.string.text_privacy_policy);
final String legalText = getString(
        R.string.text_legal_notice,
        termsConditionsText,
        privacyPolicyText
);
viewBinding.textViewLegalNotice.setText(legalText);

Linkify.addLinks(
        viewBinding.textViewLegalNotice,
        Pattern.compile(termsConditionsText),
        null,
        null,
        (match, url) -> "https://policies.google.com/terms"
);
Linkify.addLinks(
        viewBinding.textViewLegalNotice,
        Pattern.compile(privacyPolicyText),
        null,
        null,
        (match, url) -> "https://policies.google.com/privacy"
);

我的代码是这样的:

<TextView
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/link"
    android:text="@string/forgot"
    android:layout_marginTop="16dp"
    android:gravity="center"
    android:linksClickable="true"/>

我的Java代码是这样的:

/*TextView action*/
        TextView textView = (TextView) findViewById(R.id.link);
        textView.setMovementMethod(LinkMovementMethod.getInstance());
        textView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(LoginActivity.this,forgot.class));
            }
        });  

这只是将链接指向另一个活动。但这个链接是可点击的,而且工作流畅。在Android Studio 1.5中测试(预览)

接受的答案是正确的,但这意味着电话号码、地图、电子邮件地址和常规链接(例如,没有href标记的http://google.com)将不再是可点击的,因为您不能在XML内容中具有自动链接。

我所发现的唯一完整的解决方案是:

Spanned text = Html.fromHtml(myString);
URLSpan[] currentSpans = text.getSpans(0, text.length(), URLSpan.class);
SpannableString buffer = new SpannableString(text);
Linkify.addLinks(buffer, Linkify.ALL);
for (URLSpan span : currentSpans) {
    int end = text.getSpanEnd(span);
    int start = text.getSpanStart(span);
    buffer.setSpan(span, start, end, 0);
}
textView.setText(buffer);
textView.setMovementMethod(LinkMovementMethod.getInstance());

TextView不应该有android:autolink。没有必要android:linksClickable="true";默认情况下是正确的。