How to handle link click events in a textView - android

I am using Jsoup to parse the a website, formatting it with Html.fromHtml()and displaying the formatted text in a textview.
Also, I'm using LinkMoveMentmethod.getInstance to make the links in the textview clickable.
When the links are clicked they fired up a chooser to choose browsers.
Please, how can I override this default behaviour.
For example, I would want to pass the clicked url to my own activity and use Jsoup to parse it also.
CODE
TextView pageContent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_page_details);
getWindow().getDecorView().setBackgroundColor(Color.WHITE);
pageContent = (TextView) findViewById(R.id.dpage_content);
}
....
private void parseHtml(String response) {
Log.d(TAG, "parsinghtml");
Document document = Jsoup.parse(response);
page_content = document.select("div.page-content").first().html();
Spanned spanned = Html.fromHtml(page_content, new UILImageGetter(pageContent, this), null );
}

You need to create your custom class which extends LinkMovementMethod.
public class LinkClickHandler extends LinkMovementMethod{
private static LinkClickHandler sInstance;
public static LinkClickHandler getInstance() {
if (sInstance == null)
sInstance = new LinkClickHandler();
return sInstance;
}
#Override
public boolean onTouchEvent(TextView widget,
Spannable buffer, MotionEvent event) {
int action = event.getAction();
if (action == MotionEvent.ACTION_UP) {
//Implement your code for handling the click.
}
return super.onTouchEvent(widget, buffer, event);
}
}
To use this, change LinkMovementMethod.getInstance to LinkClickHandler.getInstance

You can use clickable span
ClickableSpan cs = new ClickableSpan() {
#Override
public void onClick(View v) {
Log.d("main", "textview clicked");
Toast.makeText(Main.this, "textview clicked",Toast.LENGTH_SHORT).show();
} };
// set the "test " spannable.
span.setSpan(cs, 0, 5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
tv.setText(span);
tv.setMovementMethod(LinkMovementMethod.getInstance());

Related

Custom URLSpan don't trigger onClick event, using kotlin [duplicate]

Ok. These are my problems.
I need to user regular expressions to filet out everything except for letters and then I need to encase the found words within a $word tag.
With this str = str.replaceAll(pattern, "$0");.
right now I am filtering all of the right elements (punctuation, numbers etc) but its encasing every letter within each word in an a tag not the word. so how do I use the regular expression to group the letters to a word?
from "(a tag open)t(a close)(a tag open)h(a close)(a tag open)i(a close)(a tag open)s(a close) (a tag open)i(a close)(a tag open)s(a close) (a tag open)w(a close)(a tag open)r(a close)(a tag open)o(a close)(a tag open)n(a close)(a tag open)g(a close)";
to :
"(a tag open)This(a close) (a tag open)is(a close) (a tag open)right(a close)";
then I'm making them clickable and I need to catch the click event and get the position on screen on the clicked word as I want to use the clicked event to make a tool tip show up just below the clicked word. thank you for your help.
public class MainActivity extends Activity {
public String text = "This is just a sentence to test you. 23 this is another number23!g?";
public TextView tv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = explode(text);
tv = (TextView) findViewById(R.id.tv1);
tv.setLinksClickable(true);
tv.setMovementMethod(LinkMovementMethod.getInstance());
Spanned article = Html.fromHtml(text, null, null);
setHTML(article);
}
public void setHTML(Spanned html) {
SpannableString message = new SpannableString(html.toString());
Object[] spans = html.getSpans(0, html.length(), Object.class);
for (Object span : spans) {
int start = html.getSpanStart(span);
int end = html.getSpanEnd(span);
int flags = html.getSpanFlags(span);
if (span instanceof URLSpan) {
URLSpan urlSpan = (URLSpan) span;
span = new CallbackSpan(urlSpan.getURL());
}
message.setSpan(span, start, end, flags);
}
tv.setText(message);
}
public String explode(String str){
String pattern = "([a-zA-Z])";
str = str.replaceAll(pattern, "$0");
return str;
}
private final class CallbackSpan extends ClickableSpan {
private String m_data;
private String url_main;
public CallbackSpan(String url) {
m_data = url.substring(0);
url_main = url;
}
public void onClick(View view) {
TextView item = (TextView)findViewById(R.id.tv2);
item.setText(url_main + " was clicked.");
Log.d("item", url_main);
}
}
}
Latest code ,pls see link form github
message.setSpan(span, start, end, flags);
You need remove origin span before set new span.
Please see below
The onClick() of ClickableSpan is not working for URLSpan?
EDIT
You can capture any span click event by extends LinkMovementMethod
import android.os.Handler;
import android.os.Message;
import android.text.Layout;
import android.text.Selection;
import android.text.Spannable;
import android.text.method.LinkMovementMethod;
import android.text.method.MovementMethod;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.widget.TextView;
import java.lang.ref.WeakReference;
public class LinkMovementMethodExt extends LinkMovementMethod {
public static final int LinkMovementMethod_Down = 1001;
public static final int LinkMovementMethod_Up = 2002;
private static LinkMovementMethod sInstance;
private Class mSpanClass = null;
private WeakReference<Handler> mWeakReference = null;
public static MovementMethod getInstance(Handler handler, Class spanClass) {
if (sInstance == null) {
sInstance = new LinkMovementMethodExt();
((LinkMovementMethodExt) sInstance).mWeakReference = new WeakReference<>(handler);
((LinkMovementMethodExt) sInstance).mSpanClass = spanClass;
}
return sInstance;
}
#Override
public boolean onTouchEvent(TextView widget, Spannable buffer,
MotionEvent event) {
int action = event.getAction();
if (action == MotionEvent.ACTION_UP ||
action == MotionEvent.ACTION_DOWN) {
int x = (int) event.getX();
int y = (int) event.getY();
x -= widget.getTotalPaddingLeft();
y -= widget.getTotalPaddingTop();
x += widget.getScrollX();
y += widget.getScrollY();
Layout layout = widget.getLayout();
int line = layout.getLineForVertical(y);
int off = layout.getOffsetForHorizontal(line, x);
/**
* get you interest span
*/
Object[] spans = buffer.getSpans(off, off, mSpanClass);
if (spans.length != 0) {
if (action == MotionEvent.ACTION_DOWN) {
Selection.setSelection(buffer, buffer.getSpanStart(spans[0]), buffer.getSpanEnd(spans[0]));
MessageSpan obj = new MessageSpan();
obj.setObj(spans);
obj.setView(widget);
Handler handler = mWeakReference.get();
if (handler != null) {
Message message = handler.obtainMessage();
message.obj = obj;
message.what = LinkMovementMethod_Down;
message.sendToTarget();
return true;
}
return false;
} else if (action == MotionEvent.ACTION_UP) {
Handler handler = mWeakReference.get();
if (handler != null) {
MessageSpan obj = new MessageSpan();
obj.setView(widget);
Message message = handler.obtainMessage();
message.obj = obj;
message.what = LinkMovementMethod_Up;
message.sendToTarget();
return true;
}
return false;
}
}
}
return super.onTouchEvent(widget, buffer, event);
}
public boolean canSelectArbitrarily() {
return true;
}
public boolean onKeyUp(TextView widget, Spannable buffer, int keyCode,
KeyEvent event) {
return false;
}
textView.setMovementMethod(LinkMovementMethodExt.getInstance());
Edit for "android developer"
It is better way to add Handler property for LinkMovementMethodExt class.
You can capture all Spanned which are delivered as Message object.
Snip code in onTouchEvent method:
Message message = Handler.obtainMessage();
message.obj = buffer.getSpans(off, off, Spanned.class);//get all spanned
message.what = 111;//which value ,it is up to you
message.sendToTarget(); //send message to you target handler
You can handler expected spanned in you handler class. May be it is flexible way to handle .
Hope to help you.
Above textview text is <a href='/a'>aaaa</a>123456<a href='/b'>bbbb</b>7890
I understand you requirement : Click 'aaaa',you want get its href value '/a', click 'bbbb',get its href '/b'; Do not trigger default action which is opened in web browser.
If my understand is right, you can do like this:
Set LinkMovementMethod for textview, etc:textview.setMovementMethod(LinkMovementMethodExt.getInstance(handler, URLSpan.class));
Get interest span, here is URLSpan.
In you handler handleMessage method, you can do like this:
private Handler handler = new Handler() {
public void handleMessage(Message msg) {
int what = msg.what;
if (what == 100) {
Object[] spans = (Object[])msg.obj;
for (Object span : spans) {
if (span instanceof URLSpan) {
System.out.println(((URLSpan) span).getURL());
}
}
}
};
};
Download demo code
MainActivity has color property which you can assign which color value as you like.
How to do?
Step1, get current click span.
Step2, set BackgroundColorSpan for current click span
Assuming You want click individual words on the textview?. I din't understand the converts all letters to words in your comment.
The below can be used to click on individual works and it is displayed in a toast.
public class MainActivity extends Activity {
TextView _tv;
String[] each;
SpannableString ss1;
Button b;
EditText et;
String s;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
b= (Button) findViewById(R.id.button1);
et = (EditText) findViewById(R.id.ed);
_tv = (TextView) findViewById( R.id.tv );
b.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
s=et.getText().toString();
_tv.setText("");
for(int i=0;i<s.length();i++)
{
each = s.split("\\s+");
}
for(int i=0;i<each.length;i++)
{
System.out.println("................"+each[i]);
ss1= new SpannableString(each[i]);
//StyleSpan boldSpan = new StyleSpan( Typeface.BOLD );
//spannable.setSpan( boldSpan, 41, 52, Spannable.SPAN_INCLUSIVE_INCLUSIVE );
ss1.setSpan(new MyClickableSpan(each[i]), 0, ss1.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
_tv.append(ss1);
_tv.append(" ");
}
_tv.setMovementMethod(LinkMovementMethod.getInstance());
}
});
}
class MyClickableSpan extends ClickableSpan{
String clicked;
public MyClickableSpan(String string) {
// TODO Auto-generated constructor stub
clicked =string;
}
//clickable span
public void onClick(View textView) {
//do something
Toast.makeText(MainActivity.this,clicked ,
Toast.LENGTH_SHORT).show();
}
#Override
public void updateDrawState(TextPaint ds) {
ds.setColor(Color.BLACK);//set text color
ds.setUnderlineText(false); // set to false to remove underline
}
}
}

android change one word color on touch

I want to change the color of one word when I touch it.
For example: Hello, my name is Robert.
(by default, all black)
Now if the user touches the word "Robert", I want the color of "Robert" to change to RED.
How do I do that? (I'm new to Android)
textview.setTextColor() changes the whole thing, I only want one word.
I believe the SpannableString and ClickableSpan are the things you are looking for.
For more information, check this.
And Html.fromHtml is also work for this.
L. Swifter is on the right track.
Here's a very simple version you can build off of.
SpannableString spannableString = new SpannableString(yourstring);
ClickableSpan clickableSpan = new ClickableSpan() {
boolean clicked = false;
#Override
public void onClick(View view) {
clicked = true;
view.invalidate();
}
#Override
public void updateDrawState(TextPaint ds) {
if (this.clicked) ds.setColor(Color.RED);
}
};
spannableString.setSpan(clickableSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
textview.setText(spannableString);
textview.setMovementMethod(LinkMovementMethod.getInstance());
start and end are the index positions of "Robert"
Make sure your setText is using the spannableString, not the original string.
Have fun!
You can add an HTML <font> tag to the TextView's text.
Use onTouch to calculate which word you just touched, look at this.
And :
TextView.setText(Html.fromHtml("assumble your html style string to change specified word color"));
Summarize the answer of L. Swifter and TML, also used the answer from
select a word on a tap in TextView/EditText
The following code should be work if you click any word in the TextView.
The color would be changed to red if you clicked it. Other words color will be reset to black.
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView lTextView = (TextView) findViewById(R.id.textView);
breakEveryWord("Clickable words in text view ", lTextView);
}
...
private void breakEveryWord(String passage, final TextView pTextView) {
String definition = passage.trim();
pTextView.setMovementMethod(LinkMovementMethod.getInstance());
pTextView.setText(definition, TextView.BufferType.SPANNABLE);
final Spannable spans = (Spannable) pTextView.getText();
BreakIterator iterator = BreakIterator.getWordInstance(Locale.US);
iterator.setText(definition);
int start = iterator.first();
for (int end = iterator.next(); end != BreakIterator.DONE; start = end, end = iterator
.next()) {
String possibleWord = definition.substring(start, end);
if (Character.isLetterOrDigit(possibleWord.charAt(0))) {
ClickableSpan clickSpan = new CustomClickableSpan(possibleWord, new CallBack() {
#Override
public void clearAll() {
CustomClickableSpan[] toRemoveSpans = spans.getSpans(0, pTextView.getText().length(), CustomClickableSpan.class);
for (CustomClickableSpan toRemoveSpan : toRemoveSpans) {
toRemoveSpan.reset(pTextView);
}
}
});
spans.setSpan(clickSpan, start, end,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
public static class CustomClickableSpan extends ClickableSpan {
final String mWord;
boolean clicked = false;
final CallBack mCallBack;
public CustomClickableSpan(String pWord, CallBack pCallBack) {
mWord = pWord;
mCallBack = pCallBack;
}
public void reset(View widget) {
clicked = false;
widget.invalidate();
}
#Override
public void onClick(View widget) {
Log.d("tapped on:", mWord);
mCallBack.clearAll();
clicked = true;
widget.invalidate();
}
#Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
ds.setColor(Color.BLACK);
if (this.clicked) ds.setColor(Color.RED);
}
}
public interface CallBack {
void clearAll();
}
}

Not Returning to App After Following Link

Content is delivered to my app from a server, sometimes the content contains tel: or mailto: hyperlinks. Currently I use html.fromhtml() and setMovementMethod to make the textview links clickable:
((TextView) findViewById(R.id.c_data)).setText(Html.fromHtml(HTML_out));
((TextView) findViewById(R.id.c_data)).setMovementMethod(LinkMovementMethod.getInstance());
and this works, allows the user to open mailto links, phone links and anything else.
The problem is it closes my app when they click the link, so if they click back from the phone or email it takes them back to the home screen instead of my app.
From what I can see, when the link is clicked for some reason onStop is called. How can I avoid this so the app will be re-opened right after the call/email?
example data:
<b>Title1</b>(44#) ###-####
<b>Title2</b>test#gmail.com
<b>Title3</b>google.ca
edit:
I tried to use an intent:
((TextView) findViewById(R.id.cust_data)).setText(Html.fromHtml(HTML_out));
//((TextView) findViewById(R.id.cust_data)).setMovementMethod(LinkMovementMethod.getInstance());
((TextView) findViewById(R.id.cust_data)).setMovementMethod(new MovementMethod() {
#Override
public void initialize(TextView widget, Spannable text) {
//Log.i("Test click","Good");
}
#Override
public boolean onKeyDown(TextView widget, Spannable text, int keyCode, KeyEvent event) {
return false;
}
#Override
public boolean onKeyUp(TextView widget, Spannable text, int keyCode, KeyEvent event) {
//Log.i("Test click","Good");
return false;
}
#Override
public boolean onKeyOther(TextView view, Spannable text, KeyEvent event) {
//Log.i("Test click","Good");
return false;
}
#Override
public void onTakeFocus(TextView widget, Spannable text, int direction) {
}
#Override
public boolean onTrackballEvent(TextView widget, Spannable text, MotionEvent event) {
return false;
}
#Override
public boolean onTouchEvent(TextView widget, Spannable text, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
Log.i("Test click", text.toString());
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:0123456789"));
startActivity(intent);
return true;
} else {
return false;
}
}
#Override
public boolean onGenericMotionEvent(TextView widget, Spannable text, MotionEvent event) {
return false;
}
#Override
public boolean canSelectArbitrarily() {
return false;
}
});
Just to text I used a static phone number. This still doesn't take me back to my app after.
From your last comment it sounds like you are going to possibly have several links inside of one textview. If that's the case then what you want is to set the text with a spannable, which allows you to determine what links are in there, what their text says, and other formatting like bold or italic text for only part of the text. Try something like this:
final SpannableStringBuilder content = getContent(); // This method is explained below.
final TextView textView = (TextView) findViewById(R.id.my_text_view);
textView.setLinksClickable(true);
textView.setText(content, TextView.BufferType.SPANNABLE);
textView.setMovementMethod(LinkMovementMethod.getInstance());
getContent() - This is where it will be more difficult to give you an answer, since we don't know how you're getting your links. When I wrote an application that did this it was pulling data from an xml file, so the links were marked in it. I will paste that code, so you can base yours off of it, but unless you are doing exactly the same as we were then you'll have to modify it to get your links.
if (contentNode instanceof Element && contentNode.getNodeName().equals("section")) {
String sectionTitle = ((Element) contentNode).getAttribute("title");
article.headers.add(sectionTitle);
NodeList sectionList = contentNode.getChildNodes();
String text = "";
ArrayList<String> links = new ArrayList<>(), linkStrings = new ArrayList<>();
for (int k = 0; k < sectionList.getLength(); k++) {
Node sectionNode = sectionList.item(k);
if (sectionNode instanceof Element && sectionNode.getNodeName().equals("text")) {
NodeList textNodes = sectionNode.getChildNodes();
for (int l = 0; l < textNodes.getLength(); l++) {
Node attributeNode = textNodes.item(l);
text += attributeNode.getTextContent();
}
}
if (sectionNode instanceof Element && sectionNode.getNodeName().equals("embedded_link")) {
String linkDestination = ((Element) sectionNode).getAttribute("destination");
String linkString = ((Element) sectionNode).getAttribute("string");
linkStrings.add(linkString);
links.add(linkDestination);
}
} // end k forloop
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(text);
// Loop through all of the links.
for (int m = 0; m < links.size(); m++) {
final String linkString = linkStrings.get(m);
final String link = links.get(m);
final int start = text.indexOf(linkString);
final int end = start + linkString.length();
ClickableSpan clickableSpan = new ClickableSpan() {
#Override
public void onClick(View widget) {
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(link));
context.startActivity(i);
}
};
if (start > -1) {
try {
spannableStringBuilder.setSpan(clickableSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} catch (Exception e) {
Log.e("couldn't spannable text", linkString);
}
}
} // end m forloop
article.bodyContent.put(sectionTitle, spannableStringBuilder);
} // end if for section
Hopefully that all isn't too confusing. If you have more questions let me know.

android - How to set the portion of the text is clickable

I have one TextView. In this view I want to make it as some portion of text is clickable. if you click on that text then I want to open WebView.
I did the following way:
textView.setText(Html.fromHtml("I have read and agree to the " +
"<a href='id.web.freelancer.example.TCActivity://Kode'>TERMS AND CONDITIONS</a>"));
textView.setClickable(true);
textView.setMovementMethod(LinkMovementMethod.getInstance());
Here if you click on the TERMS AND CONDITIONS then it opens in the browser but I want to open it in the WebView.
Another way, borrows a bit from Linkify but allows you to customize your handling.
Custom Span Class:
public class ClickSpan extends ClickableSpan {
private OnClickListener mListener;
public ClickSpan(OnClickListener listener) {
mListener = listener;
}
#Override
public void onClick(View widget) {
if (mListener != null) mListener.onClick();
}
public interface OnClickListener {
void onClick();
}
}
Helper function:
public static void clickify(TextView view, final String clickableText,
final ClickSpan.OnClickListener listener) {
CharSequence text = view.getText();
String string = text.toString();
ClickSpan span = new ClickSpan(listener);
int start = string.indexOf(clickableText);
int end = start + clickableText.length();
if (start == -1) return;
if (text instanceof Spannable) {
((Spannable)text).setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} else {
SpannableString s = SpannableString.valueOf(text);
s.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
view.setText(s);
}
MovementMethod m = view.getMovementMethod();
if ((m == null) || !(m instanceof LinkMovementMethod)) {
view.setMovementMethod(LinkMovementMethod.getInstance());
}
}
Usage:
clickify(textView, clickText,new ClickSpan.OnClickListener()
{
#Override
public void onClick() {
// do something
}
});
try this may it works
SpannableString span = new SpannableString(
"Click here to for gmail page.");
span.setSpan(new URLSpan("http://www.gmail.com"), 6, 10,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
TextView tv = (TextView) findViewById(R.id.text);
tv.setText(span);
tv.setMovementMethod(LinkMovementMethod.getInstance());
change start and end position according to your text size
How do I make links in a TextView clickable?
or u can create a linear layout with horizontal orientation having 2 textviews making second textview clickable..
Why don't you make the textView call on onClick method:
<TextView
...
android:onClick"openWebView"
...
/>
And then just have a method in your activity called:
public void openWebView (View v) {
....
// Do something
}

Get the value of link text when clicked in a textview in android

I have a TextView. I have added custom links like "#abc", "#android" by matching some regex pattern. The links are displaying properly. However I am not getting a way to extract the text of the link which is clicked. I am using SpannableString to setText to the textview. I then set spans using my custom ClickableSpan. It works fine. Plus I can also catch the onclick event. But the onClick() method has a View paramter. If I call getText() on the View (ofcourse after typecasting it to TextView), it returns the entire text.
I searched a lot but always found ways to add links and catch the event, but none told about getting the text of the link.
This is the code I am using to add links and recieve onclick. I got the code from one of the SO threads..
Pattern pattern = Pattern.compile("#[\\w]+");
Matcher matcher = pattern.matcher(tv.getText());//tv is my TextView
while (matcher.find()) {
int x = matcher.start();
int y = matcher.end();
final android.text.SpannableString f = new android.text.SpannableString(
tv.getText());
f.setSpan(new InternalURLSpan(new View.OnClickListener() {
public void onClick(View v) {
showDialog(1);
}
}), x, y, android.text.Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
tv.setText(f);
tv.setLinkTextColor(Color.rgb(19, 111, 154));
tv.setLinksClickable(true);
Here is the InternalURLSpan:
class InternalURLSpan extends android.text.style.ClickableSpan {
View.OnClickListener mListener;
public InternalURLSpan(View.OnClickListener listener) {
mListener = listener;
}
#Override
public void onClick(View widget) {
mListener.onClick(widget);
TextView tv = (TextView) widget;
System.out.println("tv.gettext() :: " + tv.getText());
Toast.makeText(MyActivity.this,tv.getText(),
Toast.LENGTH_SHORT).show();
}
}
Is it possible to get the text of the link clicked?
If not, is there a way of associating some data to a particular link and knowing which link gets clicked?
Any pointers.
Thanks
The solution goes like this -
Call setLinks() with you textview and the text to be added.
setLinks(textView, text);
setLinks() function is as -
void setLinks(TextView tv, String text) {
String[] linkPatterns = {
"([Hh][tT][tT][pP][sS]?:\\/\\/[^ ,'\">\\]\\)]*[^\\. ,'\">\\]\\)])",
"#[\\w]+", "#[\\w]+" };
for (String str : linkPatterns) {
Pattern pattern = Pattern.compile(str);
Matcher matcher = pattern.matcher(tv.getText());
while (matcher.find()) {
int x = matcher.start();
int y = matcher.end();
final android.text.SpannableString f = new android.text.SpannableString(
tv.getText());
InternalURLSpan span = new InternalURLSpan();
span.text = text.substring(x, y);
f.setSpan(span, x, y,
android.text.Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
tv.setText(f);
// tv.setOnLongClickListener(span.l);
}
}
tv.setLinkTextColor(Color.BLUE);
tv.setLinksClickable(true);
tv.setMovementMethod(LinkMovementMethod.getInstance());
tv.setFocusable(false);
}
and the InternalURLSpan class goes like this -
class InternalURLSpan extends android.text.style.ClickableSpan {
public String text;
#Override
public void onClick(View widget) {
handleLinkClicked(text);
}
}
handleLinkClicked() is as -
public void handleLinkClicked(String value) {
if (value.startsWith("http")) { // handle http links
} else if (value.startsWith("#")) { // handle #links
} else if (value.startsWith("#")) { // handle #links
}
}
Here is a pretty simple solution I found to get the value of the link inside the TextView when the user clicks on it. In this case I'm using phone numbers and it works like a charm.
myTextView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(myTextView.getSelectionStart()== -1 &&
myTextView.getSelectionEnd() == -1){
Toast.makeText(getApplicationContext(), "You clicked outside the link",
Toast.LENGTH_SHORT).show();
}
else {
int start = myTextView.getSelectionStart();
int end = myTextView.getSelectionEnd();
String selected = myTextView.getText().toString().substring(start, end);
Toast.makeText(getApplicationContext(),
"Clicked: " + selected,
Toast.LENGTH_SHORT).show();
}
}
});
Hope it helps.
Use
android:linksClickable="true"
android:autoLink="web"
textView.setMovementMethod(LinkMovementMethod.getInstance())

Categories

Resources