How to click or tap on a TextView text on different words?
Solution 1
I finally figured it out how to have multiple clickable parts in a TextView. It is important that they all have their own ClickableSpan! That is where I went wrong the first time testing it. If they have the same ClickableSpan instance, only the last set span is remembered.
I created a String with the required clickable area's surrounded by "[" and "]".
String sentence = "this is [part 1] and [here another] and [another one]";
and here is the set TextView, the setMovementMehthod is also mandatory:
textView.setMovementMethod(LinkMovementMethod.getInstance());
textView.setText(addClickablePart(sentence), BufferType.SPANNABLE);
I have created this function, which will handle the creation of the clickable area's:
private SpannableStringBuilder addClickablePart(String str) {
SpannableStringBuilder ssb = new SpannableStringBuilder(str);
int idx1 = str.indexOf("[");
int idx2 = 0;
while (idx1 != -1) {
idx2 = str.indexOf("]", idx1) + 1;
final String clickString = str.substring(idx1, idx2);
ssb.setSpan(new ClickableSpan() {
@Override
public void onClick(View widget) {
Toast.makeText(getView().getContext(), clickString,
Toast.LENGTH_SHORT).show();
}
}, idx1, idx2, 0);
idx1 = str.indexOf("[", idx2);
}
return ssb;
}
Solution 2
Based on Boy's response (and thank you for your response which helped me a lot), here is another way I implemented it without this '[' and ']' chars using an inner class to describe clickable words :
import java.util.List;
import android.content.Context;
import android.text.SpannableStringBuilder;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.util.AttributeSet;
import android.widget.TextView;
/**
* Defines a TextView widget where user can click on different words to see different actions
*
*/
public class ClickableTextView extends TextView {
public ClickableTextView(Context context) {
super(context);
}
public ClickableTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ClickableTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public void setTextWithClickableWords(String text, List<ClickableWord> clickableWords) {
setMovementMethod(LinkMovementMethod.getInstance());
setText(addClickablePart(text, clickableWords), BufferType.SPANNABLE);
}
private SpannableStringBuilder addClickablePart(String str, List<ClickableWord> clickableWords) {
SpannableStringBuilder ssb = new SpannableStringBuilder(str);
for (ClickableWord clickableWord : clickableWords) {
int idx1 = str.indexOf(clickableWord.getWord());
int idx2 = 0;
while (idx1 != -1) {
idx2 = idx1 + clickableWord.getWord().length();
ssb.setSpan(clickableWord.getClickableSpan(), idx1, idx2, 0);
idx1 = str.indexOf(clickableWord.getWord(), idx2);
}
}
return ssb;
}
public static class ClickableWord {
private String word;
private ClickableSpan clickableSpan;
public ClickableWord(String word, ClickableSpan clickableSpan) {
this.word = word;
this.clickableSpan = clickableSpan;
}
/**
* @return the word
*/
public String getWord() {
return word;
}
/**
* @return the clickableSpan
*/
public ClickableSpan getClickableSpan() {
return clickableSpan;
}
}
}
Hope this may help someone
EDIT : how to change link color and remove underline:
Create and use your own implementation of ClickableSpan like this :
//a version of ClickableSpan without the underline
public static class NoUnderlineClickableSpan extends ClickableSpan {
private int color = -1;
public void setColor(int color) {
this.color = color;
}
@Override
public void updateDrawState(TextPaint ds) {
ds.setUnderlineText(false);
if (this.color != -1) {
ds.setColor(this.color);
}
}
}
Solution 3
It's much simpler to use HTML with links in TextView than creating multiple TextViews, taking care about layout, listeners etc.
In your activity or fragment:
TextView mText = (TextView) findViewById(R.id.text_linkified);
mText.setText(Html.fromHtml("Open <a href='myapp://my-activity'>My Activity</a> or" +
" <a href='myapp://other-activity'>Other Activity</a>"));
mText.setMovementMethod(LinkMovementMethod.getInstance());
In manifest
<activity android:name=".MyActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="myapp" android:host="my-activity"/>
</intent-filter>
</activity>
<activity android:name=".MyOtherActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="myapp" android:host="other-activity" />
</intent-filter>
</activity>
Solution 4
I recommend this library: https://github.com/klinker24/Android-TextView-LinkBuilder
it fits your requirement very well.
A quick overview:
copied form project's readme:
- Specify long and short click actions of a specific word within your TextView
- Provide user feedback by highlighting the text when the user touches it Match single strings or use a regular expression to set clickable links to any text conforming to that pattern
- Change the color of the linked text
- Modify the transparency of the text's highlighting when the user touches it
- Set whether or not you want the text underlined
The main advantage to using this library over TextView's autolink functionality is that you can link anything, not just web address, emails, and phone numbers. It also provides color customization and touch feedback.
RajaReddy PolamReddy
I love programming. I mostly code in "Android", "ActionScript", "Adobe Flash", Adobe AS3, iOS, Objective-C . My App.. Image Crop Current applications BingoBash and Slots Bash SOreadytohelp
Updated on June 13, 2022Comments
-
RajaReddy PolamReddy almost 2 years
How to move to another view by click on text view with two different words. this is the string i am using.
By clicking Sign Up, you are indicating that you have read and agree to the Term of Use and Privacy Policy.
i want to make these two words (Term of Use, Privacy Policy) in different color and clickable..
i know ho to make color for a particular word. i want to make it clickable .
-
RajaReddy PolamReddy about 12 yearsi am not using url here just text i want to open new activity by clicking on text.
-
pawelzieba about 12 yearsIf the text is not changing, for example it's declared in strings.xml then this is the way to do it. Just declare "clickable" texts as a url with actions pointing to your activities. In result you'll get just text which is opening new activity on click, depends on what part of text you're clicking.
-
Compaq LE2202x over 10 yearsThis is great but the displayed
sentence
String has[
and]
, should it not be included in the displayed string? -
Boy over 10 yearsYou can determine yourself if you want that, just change the source to your likings...
-
pawelzieba over 10 yearsI have edited answer because a troll was down voting.
-
Boy about 10 yearsNice! Great I could help you out with this...I think I will be using your class then again for my project :)
-
Robin Royal over 9 yearsbro this answer is awesome.You rock :-)
-
Göksel Güren over 9 yearsThank you, and @Boy Working perfect. Words look underlined and blue. How can i style it?
-
phyzalis over 9 yearsYou must define a custom ClickableSpan to use in ClickableWord. I will edit my response and add it
-
phyzalis over 9 yearsYou can have a look at my answer which is looping on all the words
-
phyzalis over 9 yearsAnd if you want to pass Parcelable object to your new Activity?
-
Boy over 9 yearsI do not know. Probably now I would create my own custom view to handle this if I would want to style it differently. Not sure though. Been a few years when I wrote this :)
-
phyzalis over 9 yearsLook at the NoUnderlineClickableSpan class I wrote in my edited response. I didn't find any other way for the underline.
-
Lorensius W. L. T about 9 yearsThank you..it really helped me.
-
dev_mg99 almost 9 yearsi want to check two tags(@ and # ) like [ ] this . can u give me any solution for do this
-
Sakthivel Appavu almost 9 yearsssb.setSpan(new ClickableSpan() { Hi, how to remove this "widget", and refresh edittext. @Override public void onClick(View widget) { // how to remove this "widget", and refresh edittext. } }, idx1, idx2, 0);
-
Rishabh Srivastava almost 9 yearshow to change the colour>
-
Narendra Singh over 8 yearsit sometimes works wrong......as when clicking here another....it shows toast message for one another
-
Boy over 8 years@DroidWormNarendra maybe
ssb
needs to be initialized each time in the while loop instead of once outside of it? -
Narendra Singh over 8 yearsokay @Boy I have a little different requirement.....lets say I have a dynamic list of words, I need to make only those words clickable in the whole text of the textview. How to do so?
-
Boy over 8 yearshave a look at the answer below, I think that will do it for you