android-Spanned from Html.fromHtml,但具有用于自定义方案的自定义ClickableSpan

我有一个TextView,它显示一些HTML代码(包括图像,ImageGetter).
html不是我的,但是我可以要求他们包括自定义方案链接,甚至标签.

目的:显示一些动态生成的内容,而无需使用嵌套的Android布局.
问题:某些链接必须在应用程序中处理(装入新片段).
不能使用receiver for action.VIEW,因为它是一个活动意图,而不是广播,并且它的使用将具有很大的上下文关系,因此只有以编程方式注册的接收者才能使用.

我正在使用textView.setText(Html.fromHtml(content.content,imageGetter,null).需要所有内容保持不变,除了某些跨度应该有我自己的onClick.我对Spanned不太熟悉,所以我知道这些选项:

>编辑从Html.fromHtml返回的SpannableStringBuilder,并用自定义的ClickableSpan替换我想要的URLSpans(如何?)
>如上所述,但是将所有内容复制到新的构建器中,将URLSpans替换为我自己的(怎么办?append仅采用CharSequence,而我得到RelativeSizeSpan,StyleSpan,ImageSpan,URLSpan …)
>手动创建Spanned.我可以针对自定义方案执行此操作,但是如何为其他所有操作复制Html.fromHtml的效果(或足够接近)?

[编辑]
感谢MH.有关信息.我之前曾尝试过,但是失败了.现在我返回到它,我发现我犯了一个错误,将错误的项目传递给setSpan的第一个参数.
如果有人感兴趣,我现在使用它:

public static interface OnSpanClickListener {
    void onClick(String url);
}
public static SpannableStringBuilder getSpannable(String source, ImageGetter imageGetter, String scheme, final OnSpanClickListener clickHandler){
    SpannableStringBuilder b = (SpannableStringBuilder) Html.fromHtml(source, imageGetter, null);
    for(URLSpan s : b.getSpans(0, b.length(), URLSpan.class)){
        String s_url = s.getURL();
        if(s_url.startsWith(scheme+"://")){
            URLSpan newSpan = new URLSpan(s_url.substring(scheme.length()+3)){
                public void onClick(View view) {
                    clickHandler.onClick(getURL());
                }
            };
            b.setSpan(newSpan, b.getSpanStart(s), b.getSpanEnd(s), b.getSpanFlags(s));
            b.removeSpan(s);
        }
    }
    return b;
}

(…)

body.setText(getSpannable(content.content, imageGetter, getResources().getString(R.string.poster_scheme), new OnSpanClickListener(){
public void onClick(String url) {
    // do whatever
}
}));

解决方法:

选项1可能是最简单的,并且大多数艰苦的工作之前已经完成.您已经大体正确了:处理完HTML之后,您可以请求所有生成的URLSpan实例并遍历它们.然后,您可以将其替换为自定义的可点击范围,以完全控制任何范围的点击.

在下面的示例中,我只是将每个URLSpan替换为该类的简单扩展,该扩展采用原始url(实际上,我应该说“ uri”)并替换其方案部分.我没有实现实际的onClick()逻辑,但是请您自己想象.

SpannableStringBuilder builder = ...
URLSpan[] spans = builder .getSpans(0, builder .length(), URLSpan.class);
for (URLSpan span : spans) {
    int start = builder .getSpanStart(span);
    int end = builder .getSpanEnd(span);
    s.removeSpan(span);
    span = new CustomURLSpan(span.getURL().replace("http://", "scheme://"));
    s.setSpan(span, start, end, 0);
}
textView.setText(builder);

如前所述,CustomURLSpan类是URLSpan的简单扩展,它采用url并覆盖onClick()方法,因此可以在此处执行我们自己的逻辑.

public class CustomURLSpan extends URLSpan {

    public CustomURLSpan(String url) {
        super(url);
    }

    @Override public void onClick(View widget) {
        // custom on click behaviour here
    }
}

一些相关的问与答基本上可以做类似的事情(可能有助于获得更多启发):

> Can I change TextView link text after using Linkify?
> Remove underline from links in TextView – Android

上一篇:在Imageview上的Android自定义listview单击获取textview数据并打开活动


下一篇:android-以编程方式将单词滚动到textview的视图中