我正在使用TextView,我在XML文件中设置了autolink="web"
属性。我还为此TextView实现了onClickListener
。问题是,当TextView中的文本包含超链接时,如果我触摸该链接,链接将在浏览器中打开,但同时onClickListener
也会触发。我不希望这样。
我想要的是,如果我触摸超链接,则不应触发clickListener。如果我触摸没有超链接的文本部分,它应该只会触发。有什么建议吗?
答案 0 :(得分:22)
您可以使用Textview类的getSelectionStart()和getSelectionEnd()函数解决此问题,
tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ClassroomLog.log(TAG, "Textview Click listener ");
if (tv.getSelectionStart() == -1 && tv.getSelectionEnd() == -1) {
//This condition will satisfy only when it is not an autolinked text
//Fired only when you touch the part of the text that is not hyperlinked
}
}
});
这可能是一个迟到的回复,但可能对那些正在寻找解决方案的人有用。
答案 1 :(得分:9)
one of the @CommonsWare post有助于拦截自动链接OnClick
事件。
private void fixTextView(TextView tv) {
SpannableString current = (SpannableString) tv.getText();
URLSpan[] spans =
current.getSpans(0, current.length(), URLSpan.class);
for (URLSpan span : spans) {
int start = current.getSpanStart(span);
int end = current.getSpanEnd(span);
current.removeSpan(span);
current.setSpan(new DefensiveURLSpan(span.getURL()), start, end,
0);
}
}
public static class DefensiveURLSpan extends URLSpan {
private String mUrl;
public DefensiveURLSpan(String url) {
super(url);
mUrl = url;
}
@Override
public void onClick(View widget) {
// openInWebView(widget.getContext(), mUrl); // intercept click event and do something.
// super.onClick(widget); // or it will do as it is.
}
}
简单地应用上面的代码如下。它将遍历所有可链接的文本,并将点击事件替换为上述事件处理程序。
fixTextView(textViewContent);
答案 2 :(得分:3)
您可以在TextView中设置属性android:links Clickable =“false”,与android:autoLink =“web”结合使用;这使链接可见,但不可点击。
答案 3 :(得分:1)
使用textView.getSelectionStart()和textView.getSelectionEnd()。如果你点击链接textView.getSelectionStart()以外的任何文本,textView.getSelectionEnd()将为-1。通过在onClickListner中使用if条件,你可以单击链接时阻止onClick操作。
//inside onClickListner
if(textView.getSelectionStart()==-1&&textView.getSlectionEnd==-1){
//onClick action
}
答案 4 :(得分:1)
如果您愿意,可以使用下一个代码,该代码允许自定义字符串中的可点击链接(基于this post):
用法:
final TextView textView = (TextView) findViewById(R.id.textView);
final Spanned text = Html.fromHtml(getString(...));
textView.setText(text);
textView.setMovementMethod(new LinkMovementMethodExt());
LinkMovementMethodExt.java
public class LinkMovementMethodExt extends LinkMovementMethod {
private static LinkMovementMethod sInstance;
public static MovementMethod getInstance() {
if (sInstance == null)
sInstance = new LinkMovementMethodExt();
return sInstance;
}
@Override
public boolean onTouchEvent(final TextView widget, final Spannable buffer, final MotionEvent event) {
final int action = event.getAction();
if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) {
final int x = (int) event.getX() - widget.getTotalPaddingLeft() + widget.getScrollX();
final int y = (int) event.getY() - widget.getTotalPaddingTop() + widget.getScrollY();
final Layout layout = widget.getLayout();
final int line = layout.getLineForVertical(y);
final int off = layout.getOffsetForHorizontal(line, x);
final ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);
if (link.length != 0) {
//do something with the clicked item...
return true;
}
}
return super.onTouchEvent(widget, buffer, event);
}
}
答案 5 :(得分:1)
private void fixTextView(TextView tv) {
SpannableString current = (SpannableString) tv.getText();
URLSpan[] spans =
current.getSpans(0, current.length(), URLSpan.class);
for (URLSpan span : spans) {
int start = current.getSpanStart(span);
int end = current.getSpanEnd(span);
current.removeSpan(span);
current.setSpan(new DefensiveURLSpan(span.getURL()), start, end,
0);
}
}
public static class DefensiveURLSpan extends URLSpan {
public final static Parcelable.Creator<DefensiveURLSpan> CREATOR =
new Parcelable.Creator<DefensiveURLSpan>() {
@Override
public DefensiveURLSpan createFromParcel(Parcel source) {
return new DefensiveURLSpan(source.readString());
}
@Override
public DefensiveURLSpan[] newArray(int size) {
return new DefensiveURLSpan[size];
}
};
private String mUrl;
public DefensiveURLSpan(String url) {
super(url);
mUrl = url;
}
@Override
public void onClick(View widget) {
// openInWebView(widget.getContext(), mUrl); // intercept click event and do something.
// super.onClick(widget); // or it will do as it is.
}
}
然后,您可以在宣布视图后通过通货膨胀或fixTextView(textViewContent);
调用findViewById
或通过addView
添加到视窗中<{1}}
这包括在扩展Parcelable时缺少设置CREATOR的要求。
它被提议作为编辑,但被拒绝。不幸的是,现在未来的用户将不得不首先找出原始的不完整的用户。好的,评论家!
答案 6 :(得分:0)
您可以尝试使用onClickListener,而不是使用onClickListener。
private void addLink() {
tvLink = (TextView) findViewById(R.id.tvInfo2);
String strURL = UrlLoader.getCodeUrl();
// Make the url string clicable and take action in its onclick
SpannableString spanUrl = SpannableString.valueOf(strURL);
spanUrl.setSpan(new InternalURLSpan(new OnClickListener() {
public void onClick(View v) {
//Do Some action
}
}), 0, spanUrl.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
tvLink.setText(spanUrl);
// We probably also want the user to jump to your link by moving the
// focus (e.g. using the trackball), which we can do by setting the
// proper movement method:
MovementMethod m = tvLink.getMovementMethod();
if ((m == null) || !(m instanceof LinkMovementMethod)) {
if (tvLink.getLinksClickable()) {
tvLink.setMovementMethod(LinkMovementMethod.getInstance());
}
}
}
同样在布局XML文件中,别忘了添加
<TextView android:layout_width="wrap_content" android:linksClickable="true"
android:layout_height="wrap_content" android:id="@+id/tvInfo2" android:text="@string/url_link" />
答案 7 :(得分:0)
只需添加
textView.setMovementMethod(CustomLinkMovementMethod.getInstance());
到 @binary 对那些方法无效的人的回答
答案 8 :(得分:0)
科林版本:
类似于Java中的较早答案。简单地:
在布局编辑器/ XML中,通过autoLink属性添加您要超链接的事物的类型。
<TextView
...
android:autoLink="web|phone|email" />
使用Kotlin代码向您的TextView添加onClickListener来处理对纯文本部分的单击。通过选中selectionStart和selectionEnd进行检查,以确保该人没有单击链接。
binding.messageText.setOnClickListener { view ->
if (binding.messageText.selectionStart == -1 && binding.messageText.selectionEnd == -1) {
// do whatever you want when they click on the plain text part
}
}