Textview Catch Clicking On Link When Autolink Is Set To "web"
Solution 1:
Actually,
I solved this by abandoning autolLink='web'
and by parsing html url, creating SpannableString
and setting additional spans.
So, let's say that I want to do the following:
- if user clicks on the part of the text of textView which is not url, method
someMethod()
should be called - if user clicks on the part of the text of textView which is url, method
someMethod()
should be called and browser should be openned with given URL
So, first we have the content which is in the variable message
and method String extractFirstLink(String text)
will be used to get the url.
privatestaticStringextractFirstLink(String text) {
Matcher m = Patterns.WEB_URL.matcher(text);
return m.find() ? m.group() : null;
}
Note: in my case I know that I will have only one url, but if you can expect more than one url, this solution (found somewhere on StackOverflow, can't find it right now) will do the work:
publicstaticString[] extractLinks(String text) {
List<String> links = newArrayList<String>();
Matcher m = Patterns.WEB_URL.matcher(text);
while (m.find()) {
String url = m.group();
links.add(url);
}
return links.toArray(newString[links.size()]);
}
So, here is the code:
intcontentTextColor= ...; // color of non-url text in textViewinturlTextColor= ...;
Stringmessage= notification.getMessage(); // content storedfinalStringfoundLink= extractFirstLink(message);
SpannableStringstyledString=newSpannableString(message);
if (foundLink != null) {
intstartPosition= message.indexOf(foundLink);
intendPosition= startPosition + foundLink.length();
styledString.setSpan(newForegroundColorSpan(urlTextColor), startPosition, endPosition, 0);
ClickableSpanclickableURLSpan=newClickableSpan() {
@OverridepublicvoidonClick(View widget) {
someMethod();
IntentbrowserIntent=newIntent(Intent.ACTION_VIEW, Uri.parse(foundLink));
widget.getContext().startActivity(browserIntent);
}
};
ClickableSpanclickableNonURLSpan1=newClickableSpan() {
@OverridepublicvoidonClick(View view) {
someMethod();
}
@OverridepublicvoidupdateDrawState(TextPaint ds) {
ds.setUnderlineText(false);
}
};
ClickableSpanclickableNonURLSpan2=newClickableSpan() {
@OverridepublicvoidonClick(View view) {
someMethod();
}
@OverridepublicvoidupdateDrawState(TextPaint ds) {
ds.setUnderlineText(false);
}
};
styledString.setSpan(clickableURLSpan, startPosition, endPosition, 0);
if (startPosition > 0) {
styledString.setSpan(clickableNonURLSpan1, 0, startPosition - 1, 0);
styledString.setSpan(newForegroundColorSpan(contentTextColor), 0, startPosition -1, 0);
}
if (endPosition < message.length() -1) {
styledString.setSpan(clickableNonURLSpan2, endPosition + 1, message.length(), 0);
styledString.setSpan(newForegroundColorSpan(contentTextColor), endPosition + 1, message.length(), 0);
}
txtView.setMovementMethod(LinkMovementMethod.getInstance());
}
txtView.setText(styledString);
There are some interesting things here. For example, when I wish to make span responsive to click, I have to use ClickableSpan
, but! I must handle situation where I have format text1-url-text2. So, since all these three parts should be ClickableSpan
s and text1 and text2 should not have underline, which is the default behaviour of it, I had to override updateDrawState
method in my implementation of ClickableSpan
for text1 and text2.
There is another catch, I had to create two implementation of ClickableSpan interface in order to have to work as intended. That's why I created clickableNonURLSpan1
and clickableNonURLSpan2
.
Post a Comment for "Textview Catch Clicking On Link When Autolink Is Set To "web""