在另一个活动中打开 TextView 的链接,而不是默认浏览器。
在另一个活动中打开 TextView 的链接,而不是默认浏览器。
将textView的autoLinkMask
设置为Linkify.ALL
,我可以打开链接,浏览器会显示网页。
我需要调用另一个活动,使用它的webView而不离开应用程序。
重要注意事项:
- 更改textView内容不是一个选项,我需要将链接显示为它们原本的模式和scheme。
- textView中有很多文本,不仅仅是链接。
我查看了movementMethod
和IntentFilters
,可能错过了一些东西,但似乎无法解决问题。
所以,有没有办法拦截textView中点击的链接,做一些操作而不打开浏览器?
如果你想提到这个 SO问题,请给出一些论据,因为它似乎不能解决我遇到的同样问题。
问题的出现原因:
在默认情况下,当用户点击TextView中的链接时,链接会在默认的浏览器中打开。然而,某些情况下,我们希望链接在另一个活动中打开,而不是默认浏览器中。
解决方法:
通过使用Textoo库,可以自定义TextView中链接的点击事件。以下是解决问题的步骤:
1. 导入Textoo库。可以在项目的build.gradle文件中添加以下依赖项:
implementation 'com.github.bluecabin:Textoo:1.5'
2. 在活动中找到要添加链接处理程序的TextView。例如,假设TextView的id为"your_text_view"。
3. 使用Textoo库的config()方法来配置TextView,并添加链接处理程序。链接处理程序是一个实现LinksHandler接口的匿名类,需要实现onClick()方法。在onClick()方法中,可以根据需要自定义处理链接的逻辑。
4. 调用apply()方法将配置应用到TextView上。
下面是一个示例代码,演示如何使用Textoo来打开TextView链接的另一个活动而不是默认浏览器:
import com.bluecabin.textoo.LinksHandler; import com.bluecabin.textoo.Textoo; TextView yourTextView = Textoo .config((TextView) findViewById(R.id.your_text_view)) .addLinksHandler(new LinksHandler() { public boolean onClick(View view, String url) { if (showInMyWebView(url)) { // // 在这里添加自定义处理逻辑 // return true; // 事件已处理 } else { return false; // 继续默认处理,即打开链接在浏览器中显示 } } }) .apply();
Textoo库的工作原理是将TextView中的URLSpan替换为自定义的ClickableSpan实现,然后将点击事件分派给用户提供的LinksHandler。这种机制与其他解决方案非常相似,只是封装在更高级的API中,使使用更加方便。
问题的原因是希望在应用的另一个活动中打开TextView链接,而不是默认浏览器。解决方法是通过添加点击监听器,将URL Spans替换为可直接添加到同一方法中的Click Listener。
首先,定义YourCustomClickableSpan类,它继承自ClickableSpan,并实现了一个接口OnClickListener。在onClick方法中,通过调用OnClickListener的onClick方法来处理点击事件。
接下来,定义RichTextUtils类,该类将操作TextView的Spanned文本。定义了一个replaceAll方法,该方法用于替换所有指定类型的Span。在方法中,先创建一个SpannableString对象,然后获取原始文本中指定类型的Span,遍历并移除每个Span,然后使用指定的转换器将其转换为ClickSpan,并重新设置到SpannableString对象中。
然后,定义URLSpanConverter类,该类实现了RichTextUtils.SpanConverter接口。在convert方法中,将URLSpan转换为ClickSpan。
最后,在使用部分,首先获取TextView的实例,并设置文本。然后使用Linkify.addLinks方法将TextView的文本中的链接转换为URLSpan。接下来,使用RichTextUtils.replaceAll方法将URLSpan替换为ClickSpan,并设置ClickSpan的OnClickListener来处理点击事件。最后,将处理完的Spannable对象重新设置到TextView中。
需要注意的是,由于所有的类都是静态的,因此可以直接将它们放在Util类中,从任何地方轻松引用。
希望这个答案能帮助有人更好地理解流程,而不只是简单地复制粘贴忘记,后者是我喜欢CommonsWare明智地省略了完整实现ClickableSpan子类的原因。
问题的出现原因:
在使用TextView时,点击TextView中的链接时,链接会默认在浏览器中打开,而不是在另一个活动中打开。
解决方法:
1. 创建一个继承自ClickableSpan的子类(例如YourCustomClickableSpan),在其onClick()方法中实现自定义的逻辑。
2. 使用一个工具类RichTextUtils,将所有的URLSpan对象批量转换为YourCustomClickableSpan对象。具体代码如下:
public class RichTextUtils { public static Spannable replaceAll(Spanned original, Class sourceType, SpanConverter 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 { B convert(A span); } }
使用方法如下:
yourTextView.setText(RichTextUtils.replaceAll((Spanned)yourTextView.getText(), URLSpan.class, new URLSpanConverter()));
其中,URLSpanConverter是一个自定义的URLSpan转换器,代码如下:
class URLSpanConverter implements RichTextUtils.SpanConverter{ public URLSpan convert(URLSpan span) { return(new YourCustomClickableSpan(span.getURL())); } }
以上代码将所有的URLSpan对象转换为YourCustomClickableSpan对象。
这个解决方法不仅在常规使用中有效,也适用于辅助功能模式下的TalkBack。
如果在TextView中的链接无法点击,可以尝试调整android:linksClickable属性的值或尝试不同的android:autoLink值。