将text {autoLinkMask
设置为Linkify.ALL
后,我可以打开链接,浏览器会显示网页。
我需要调用另一个活动来完成它的webView不会离开应用程序。
重要说明:
我浏览了movementMethod
和IntentFilters
,可能会错过一些内容,但看起来无能为力。
那么,是否有任何选项拦截TextView
中被触摸的链接,无法打开浏览器?
如果你想提及this SO问题,请提出一些论据,为什么它似乎没有解决与我相同的问题。
答案 0 :(得分:24)
步骤1:创建自己的ClickableSpan
子类,在onClick()
方法中执行您想要的操作(例如,称为YourCustomClickableSpan
)
步骤2:运行所有URLSpan
个对象的批量转换为YourCustomClickableSpan
个对象。我有一个实用工具类:
public class RichTextUtils {
public static <A extends CharacterStyle, B extends CharacterStyle> Spannable replaceAll(Spanned original,
Class<A> sourceType,
SpanConverter<A, B> converter) {
SpannableString result=new SpannableString(original);
A[] spans=result.getSpans(0, result.length(), sourceType);
for (A span : spans) {
int start=result.getSpanStart(span);
int end=result.getSpanEnd(span);
int flags=result.getSpanFlags(span);
result.removeSpan(span);
result.setSpan(converter.convert(span), start, end, flags);
}
return(result);
}
public interface SpanConverter<A extends CharacterStyle, B extends CharacterStyle> {
B convert(A span);
}
}
您可以这样使用它:
yourTextView.setText(RichTextUtils.replaceAll((Spanned)yourTextView.getText(),
URLSpan.class,
new URLSpanConverter()));
使用这样的自定义URLSpanConverter
:
class URLSpanConverter
implements
RichTextUtils.SpanConverter<URLSpan, YourCustomClickableSpan> {
@Override
public URLSpan convert(URLSpan span) {
return(new YourCustomClickableSpan(span.getURL()));
}
}
将所有URLSpan
个对象转换为YourCustomClickableSpan
个对象。
答案 1 :(得分:3)
通过添加Click Listener,我可以使@CommonsWare的代码更加优雅和清晰,可以直接添加到替换URL Spans的相同方法中。
定义YourCustomClickableSpan Class
。
public static class YourCustomClickableSpan extends ClickableSpan {
private String url;
private OnClickListener mListener;
public YourCustomClickableSpan(String url, OnClickListener mListener) {
this.url = url;
this.mListener = mListener;
}
@Override
public void onClick(View widget) {
if (mListener != null) mListener.onClick(url);
}
public interface OnClickListener {
void onClick(String url);
}
}
定义RichTextUtils Class
,它将操纵TextView的跨区文本。
public static class RichTextUtils {
public static <A extends CharacterStyle, B extends CharacterStyle> Spannable replaceAll (
Spanned original,
Class<A> sourceType,
SpanConverter<A, B> converter,
final ClickSpan.OnClickListener listener) {
SpannableString result = new SpannableString(original);
A[] spans = result.getSpans(0, result.length(), sourceType);
for (A span : spans) {
int start = result.getSpanStart(span);
int end = result.getSpanEnd(span);
int flags = result.getSpanFlags(span);
result.removeSpan(span);
result.setSpan(converter.convert(span, listener), start, end, flags);
}
return (result);
}
public interface SpanConverter<A extends CharacterStyle, B extends CharacterStyle> {
B convert(A span, ClickSpan.OnClickListener listener);
}
}
定义URLSpanConverter class
,它将使用您的自定义范围执行替换URLSpan的实际代码。
public static class URLSpanConverter
implements RichTextUtils.SpanConverter<URLSpan, ClickSpan> {
@Override
public ClickSpan convert(URLSpan span, ClickSpan.OnClickListener listener) {
return (new ClickSpan(span.getURL(), listener));
}
}
用法
TextView textView = ((TextView) this.findViewById(R.id.your_id));
textView.setText("your_text");
Linkify.addLinks(contentView, Linkify.ALL);
Spannable formattedContent = UIUtils.RichTextUtils.replaceAll((Spanned)textView.getText(), URLSpan.class, new UIUtils.URLSpanConverter(), new UIUtils.ClickSpan.OnClickListener() {
@Override
public void onClick(String url) {
// Call here your Activity
}
});
textView.setText(formattedContent);
请注意,我在这里将所有类定义为静态,因此您可以直接将其放在Util类中,然后从任何地方轻松引用它。
答案 2 :(得分:2)
只是使用我刚刚创建的Textoo分享替代解决方案:
TextView yourTextView = Textoo
.config((TextView) findViewById(R.id.your_text_view))
.addLinksHandler(new LinksHandler() {
@Override
public boolean onClick(View view, String url) {
if (showInMyWebView(url)) {
//
// Your custom handling here
//
return true; // event handled
} else {
return false; // continue default processing i.e. launch browser app to display link
}
}
})
.apply();
在库中,库使用自定义URLSpan
实现替换TextView中的ClickableSpan
,该实现将点击事件发送给用户提供的LinksHandler
(s)。该机制与@commonsWare的解决方案非常相似。只需打包更高级别的API即可使其更易于使用。
答案 3 :(得分:0)
我认为David Hedlund's answer to himself是要走的路。在我的情况下,我有一个TextView包含用户收件箱的短信内容,我想处理以下行为:
为实现这一点,我以这种方式使用了链接的答案:
TextView tvBody = (TextView)findViewById(R.id.tvBody);
tvBody.setText(messageContentString);
// now linkify it with patterns and scheme
Linkify.addLinks(tvBody, Patterns.WEB_URL, "com.my.package.web:");
Linkify.addLinks(tvBody, Patterns.PHONE, "com.my.package.tel:");
现在在清单中:
<activity
android:name=".WebViewActivity"
android:label="@string/web_view_activity_label">
<intent-filter>
<category android:name="android.intent.category.DEFAULT" />
<action android:name="android.intent.action.VIEW"/>
<data android:scheme="com.duckma.phonotto.web"/>
</intent-filter>
</activity>
...
<activity
android:name=".DialerActivity"
android:label="@string/dialer_activity_label">
<intent-filter>
<category android:name="android.intent.category.DEFAULT" />
<action android:name="android.intent.action.VIEW"/>
<data android:scheme="com.duckma.phonotto.tel"/>
</intent-filter>
</activity>
<activity
android:name=".AddressBook"
android:label="@string/address_book_activity_label">
<intent-filter>
<category android:name="android.intent.category.DEFAULT" />
<action android:name="android.intent.action.VIEW"/>
<data android:scheme="com.duckma.phonotto.tel"/>
</intent-filter>
</activity>
它对我来说很好用,当用户点击电话号码时,选择器将显示拨号器/地址簿选项。在被叫活动中,使用getIntent().getData()
查找传递的Url及其中的数据。
答案 4 :(得分:-3)
要做到这一点:
TextView textView=(TextView) findViewById(R.id.link);
textView.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent intent=new Intent(YourActivityName.this,WebActivity.class);
startActivity(intent);
}
});
onAreate of WebActivity Class:
WebView webView=(WebView) findViewById(R.id.web);
webView.loadUrl("http://www.google.co.in");
在xml:
中的textview下添加android:clickable="true"