当autoLink设置为“web”时,TextView捕获单击链接

时间:2016-09-12 15:36:43

标签: android hyperlink textview

我的布局中有autoLink='web'的TextView,当我点击它时,内部的互联网浏览器会打开,其中的URL作为TextView中的文本提供,一切都很好。我希望用它做更多的事情,即除了在浏览器中打开那个URL我想做一些额外的动作。什么是最痛苦的方法呢?

最佳,

Deveti

1 个答案:

答案 0 :(得分:1)

实际上,

我通过放弃autolLink='web'并解析html网址,创建SpannableString并设置其他跨度来解决这个问题。

所以,让我们说我想做以下事情:

  • 如果用户点击了不是网址的textView文本部分,则应调用方法someMethod()
  • 如果用户点击了textView文本的url部分,则应调用方法someMethod(),并使用给定的URL打开浏览器

因此,首先我们将使用变量message中的内容和方法String extractFirstLink(String text)来获取网址。

private static String extractFirstLink(String text) {
    Matcher m = Patterns.WEB_URL.matcher(text);
    return m.find() ? m.group() : null;
}

注意:在我的情况下,我知道我只有一个网址,但是如果你可以期待多个网址,这个解决方案(在StackOverflow上找到,现在无法找到它)将完成工作:

public static String[] extractLinks(String text) {
    List<String> links = new ArrayList<String>();
    Matcher m = Patterns.WEB_URL.matcher(text);
    while (m.find()) {
        String url = m.group();
        links.add(url);
    }
    return links.toArray(new String[links.size()]);
}

所以,这是代码:

int contentTextColor = ...; // color of non-url text in textView
int urlTextColor = ...;
String message = notification.getMessage(); // content stored
final String foundLink = extractFirstLink(message);
SpannableString styledString = new SpannableString(message);

if (foundLink != null) {
    int startPosition = message.indexOf(foundLink);
    int endPosition = startPosition + foundLink.length();
    styledString.setSpan(new ForegroundColorSpan(urlTextColor), startPosition, endPosition, 0);

    ClickableSpan clickableURLSpan = new ClickableSpan() {
        @Override
        public void onClick(View widget) {
            someMethod();
            Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(foundLink));
            widget.getContext().startActivity(browserIntent);
        }
    };

    ClickableSpan clickableNonURLSpan1 = new ClickableSpan() {
        @Override
        public void onClick(View view) {
            someMethod();
        }

        @Override
        public void updateDrawState(TextPaint ds) {
            ds.setUnderlineText(false);
        }
    };
    ClickableSpan clickableNonURLSpan2 = new ClickableSpan() {
        @Override
        public void onClick(View view) {
            someMethod();
        }

        @Override
        public void updateDrawState(TextPaint ds) {
            ds.setUnderlineText(false);
        }
    };
    styledString.setSpan(clickableURLSpan, startPosition, endPosition, 0);
    if (startPosition > 0) {
        styledString.setSpan(clickableNonURLSpan1, 0, startPosition - 1, 0);
        styledString.setSpan(new ForegroundColorSpan(contentTextColor), 0, startPosition -1, 0);
    }
    if (endPosition < message.length() -1) {
        styledString.setSpan(clickableNonURLSpan2, endPosition + 1, message.length(),  0);
        styledString.setSpan(new ForegroundColorSpan(contentTextColor), endPosition + 1, message.length(),  0);
    }

    txtView.setMovementMethod(LinkMovementMethod.getInstance());
}

txtView.setText(styledString);

这里有一些有趣的事情。例如,当我希望跨度响应点击时,我必须使用ClickableSpan,但是!我必须处理格式为text1-url-text2的情况。所以,由于所有这三个部分都应该是ClickableSpan s而text1和text2不应该有下划线,这是它的默认行为,我必须在{{1}的实现中覆盖updateDrawState方法对于text1和text2。

还有另外一个问题,我必须创建两个ClickableSpan接口的实现,以便必须按预期工作。这就是我创建ClickableSpanclickableNonURLSpan1的原因。