Hello all,
Today I am going to share a very nice example for making #hashtag and @user_name is clickable in a single string .
I have tried many example for this, but now it is working
First I have make a textview in the layout , I am assuming that the layout design is not needed to share , as It is simply a textview (having the is textview1) in a Relative Layout.
Now I have to add two base classes which is used to get the symbols(#, @) in the string
I have made two base classes one is for the @ symbol and another is for # symbol. If you want to make string clickable on any other symbol alos like: $ then you have to make another base class for $ symbol also, But for now I will work with the two base classes for the two symbols .
One base class name is : Hashtag.java (This class is for # symbol)
import android.content.Context;
import android.text.Spanned;
import android.text.TextPaint;
import android.text.style.ClickableSpan;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
public class Hashtag extends ClickableSpan{
Context context;
TextPaint textPaint;
public Hashtag(Context ctx) {
super();
context = ctx;
}
@Override
public void updateDrawState(TextPaint ds) {
textPaint = ds;
ds.setColor(ds.linkColor);
ds.setARGB(255, 30, 144, 255);
}
@Override
public void onClick(View widget) {
TextView tv = (TextView) widget;
Spanned s = (Spanned) tv.getText();
int start = s.getSpanStart(this);
int end = s.getSpanEnd(this);
String theWord = s.subSequence(start + 1, end).toString();
// you can start another activity here
Toast.makeText(context, String.format("Tag : %s", theWord), 10 ).show();
}
}
Another base class name is : CalloutLink.java (This class is for @ symbol)
import android.content.Context;
import android.graphics.Color;
import android.text.Spanned;
import android.text.TextPaint;
import android.text.style.ClickableSpan;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
public class CalloutLink extends ClickableSpan {
Context context;
public CalloutLink(Context ctx) {
super();
context = ctx;
}
@Override
public void updateDrawState(TextPaint ds) {
ds.setARGB(255, 51, 51, 51);
ds.setColor(Color.RED);
}
@Override
public void onClick(View widget) {
TextView tv = (TextView) widget;
Spanned s = (Spanned) tv.getText();
int start = s.getSpanStart(this);
int end = s.getSpanEnd(this);
String theWord = s.subSequence(start + 1, end).toString();
// you can start another activity here
Toast.makeText(context, String.format("Here's a cool person: %s", theWord), 10).show();
}
}
Now let's move to the MainActivity .java
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.libs.CalloutLink;
import com.libs.Hashtag;
import android.app.Activity;
import android.os.Bundle;
import android.text.SpannableString;
import android.text.method.LinkMovementMethod;
import android.util.Log;
import android.widget.TextView;
public class MainActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String str = "@People , You've gotta #dance like there's nobody watching,#Love like you'll never be #hurt,#Sing like there's @nobody listening,And live like it's #heaven on #earth.";
TextView txt = (TextView)findViewById(R.id.textView1);
ArrayList<int[]> hashtagSpans1 = getSpans(str, '#');
ArrayList<int[]> calloutSpans1 = getSpans(str, '@');
SpannableString commentsContent1 =
new SpannableString(str);
setSpanComment(commentsContent1,hashtagSpans1) ;
setSpanUname(commentsContent1,calloutSpans1) ;
txt.setMovementMethod(LinkMovementMethod.getInstance());
txt.setText(commentsContent1);
}
public ArrayList<int[]> getSpans(String body, char prefix) {
ArrayList<int[]> spans = new ArrayList<int[]>();
Pattern pattern = Pattern.compile(prefix + "\\w+");
Matcher matcher = pattern.matcher(body);
// Check all occurrences
while (matcher.find()) {
int[] currentSpan = new int[2];
currentSpan[0] = matcher.start();
currentSpan[1] = matcher.end();
spans.add(currentSpan);
}
return spans;
}
private void setSpanComment(SpannableString commentsContent, ArrayList<int[]> hashtagSpans) {
for(int i = 0; i < hashtagSpans.size(); i++) {
int[] span = hashtagSpans.get(i);
int hashTagStart = span[0];
int hashTagEnd = span[1];
commentsContent.setSpan(new Hashtag(MainActivity.this),
hashTagStart,
hashTagEnd, 0);
}
}
private void setSpanUname(SpannableString commentsUname, ArrayList<int[]> calloutSpans) {
for(int i = 0; i < calloutSpans.size(); i++) {
int[] span = calloutSpans.get(i);
int calloutStart = span[0];
int calloutEnd = span[1];
commentsUname.setSpan(new CalloutLink(MainActivity.this),
calloutStart,
calloutEnd, 0);
}
}
}
That's all , no permission is required in the menifest.
I am attaching the screen shot for this task:
Today I am going to share a very nice example for making #hashtag and @user_name is clickable in a single string .
I have tried many example for this, but now it is working
First I have make a textview in the layout , I am assuming that the layout design is not needed to share , as It is simply a textview (having the is textview1) in a Relative Layout.
Now I have to add two base classes which is used to get the symbols(#, @) in the string
I have made two base classes one is for the @ symbol and another is for # symbol. If you want to make string clickable on any other symbol alos like: $ then you have to make another base class for $ symbol also, But for now I will work with the two base classes for the two symbols .
One base class name is : Hashtag.java (This class is for # symbol)
import android.content.Context;
import android.text.Spanned;
import android.text.TextPaint;
import android.text.style.ClickableSpan;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
public class Hashtag extends ClickableSpan{
Context context;
TextPaint textPaint;
public Hashtag(Context ctx) {
super();
context = ctx;
}
@Override
public void updateDrawState(TextPaint ds) {
textPaint = ds;
ds.setColor(ds.linkColor);
ds.setARGB(255, 30, 144, 255);
}
@Override
public void onClick(View widget) {
TextView tv = (TextView) widget;
Spanned s = (Spanned) tv.getText();
int start = s.getSpanStart(this);
int end = s.getSpanEnd(this);
String theWord = s.subSequence(start + 1, end).toString();
// you can start another activity here
Toast.makeText(context, String.format("Tag : %s", theWord), 10 ).show();
}
}
Another base class name is : CalloutLink.java (This class is for @ symbol)
import android.content.Context;
import android.graphics.Color;
import android.text.Spanned;
import android.text.TextPaint;
import android.text.style.ClickableSpan;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
public class CalloutLink extends ClickableSpan {
Context context;
public CalloutLink(Context ctx) {
super();
context = ctx;
}
@Override
public void updateDrawState(TextPaint ds) {
ds.setARGB(255, 51, 51, 51);
ds.setColor(Color.RED);
}
@Override
public void onClick(View widget) {
TextView tv = (TextView) widget;
Spanned s = (Spanned) tv.getText();
int start = s.getSpanStart(this);
int end = s.getSpanEnd(this);
String theWord = s.subSequence(start + 1, end).toString();
// you can start another activity here
Toast.makeText(context, String.format("Here's a cool person: %s", theWord), 10).show();
}
}
Now let's move to the MainActivity .java
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.libs.CalloutLink;
import com.libs.Hashtag;
import android.app.Activity;
import android.os.Bundle;
import android.text.SpannableString;
import android.text.method.LinkMovementMethod;
import android.util.Log;
import android.widget.TextView;
public class MainActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String str = "@People , You've gotta #dance like there's nobody watching,#Love like you'll never be #hurt,#Sing like there's @nobody listening,And live like it's #heaven on #earth.";
TextView txt = (TextView)findViewById(R.id.textView1);
ArrayList<int[]> hashtagSpans1 = getSpans(str, '#');
ArrayList<int[]> calloutSpans1 = getSpans(str, '@');
SpannableString commentsContent1 =
new SpannableString(str);
setSpanComment(commentsContent1,hashtagSpans1) ;
setSpanUname(commentsContent1,calloutSpans1) ;
txt.setMovementMethod(LinkMovementMethod.getInstance());
txt.setText(commentsContent1);
}
public ArrayList<int[]> getSpans(String body, char prefix) {
ArrayList<int[]> spans = new ArrayList<int[]>();
Pattern pattern = Pattern.compile(prefix + "\\w+");
Matcher matcher = pattern.matcher(body);
// Check all occurrences
while (matcher.find()) {
int[] currentSpan = new int[2];
currentSpan[0] = matcher.start();
currentSpan[1] = matcher.end();
spans.add(currentSpan);
}
return spans;
}
private void setSpanComment(SpannableString commentsContent, ArrayList<int[]> hashtagSpans) {
for(int i = 0; i < hashtagSpans.size(); i++) {
int[] span = hashtagSpans.get(i);
int hashTagStart = span[0];
int hashTagEnd = span[1];
commentsContent.setSpan(new Hashtag(MainActivity.this),
hashTagStart,
hashTagEnd, 0);
}
}
private void setSpanUname(SpannableString commentsUname, ArrayList<int[]> calloutSpans) {
for(int i = 0; i < calloutSpans.size(); i++) {
int[] span = calloutSpans.get(i);
int calloutStart = span[0];
int calloutEnd = span[1];
commentsUname.setSpan(new CalloutLink(MainActivity.this),
calloutStart,
calloutEnd, 0);
}
}
}
That's all , no permission is required in the menifest.
I am attaching the screen shot for this task:
screenshots for #tag and @username clickable textview
Please leave a comment if you have any query regarding to this example