Android Linkify text - Spannable Text in Single Text View - As like Twitter tweet
I have used the same thing which I answered here in This Question
For that I have used this LinkEnabledTextView and that become easy for me to do the task.
Android Linkify both web and @mentions all in the same TextView
Here's my code to linkify all Twitter links (mentions, hashtags and URLs):
TextView tweet = (TextView) findViewById(R.id.tweet);
TransformFilter filter = new TransformFilter() {
public final String transformUrl(final Matcher match, String url) {
return match.group();
}
};
Pattern mentionPattern = Pattern.compile("@([A-Za-z0-9_-]+)");
String mentionScheme = "http://www.twitter.com/";
Linkify.addLinks(tweet, mentionPattern, mentionScheme, null, filter);
Pattern hashtagPattern = Pattern.compile("#([A-Za-z0-9_-]+)");
String hashtagScheme = "http://www.twitter.com/search/";
Linkify.addLinks(tweet, hashtagPattern, hashtagScheme, null, filter);
Pattern urlPattern = Patterns.WEB_URL;
Linkify.addLinks(tweet, urlPattern, null, null, filter);
How to make ListItem Textview to work as Twitter Tweets and get Different Linkify clicks?
For twitter app, I had also the same requirement to click on handles of tweets and also click on the text of tweet to get Tweet detail.
For that I have used this LinkEnabledTextView and that become easy for me to do the task.
I just added the class in my project and then in List Item instead simple TextView I used object/instance of the LinkEnabledTextView.
There is a complete demo in above link, Please check that.
EDIT: Adapter Code Specially check onTextLinkClick() and then holder.twtdata.setOnClickListener()
private static class EfficientAdapter extends BaseAdapter implements TextLinkClickListener {
private LayoutInflater mInflater;
static int pos =0;
public EfficientAdapter(Context context) {
mInflater = LayoutInflater.from(context);
}
public int getCount() {
return timelines.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(final int position, View convertView,
ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.listtimerow, null);
holder = new ViewHolder();
holder.twtdata = (LinkEnabledTextView) convertView
.findViewById(R.id.twtdata);
holder.twtnm = (TextView) convertView
.findViewById(R.id.twthandle);
holder.twtimg = (ImageView) convertView
.findViewById(R.id.avatar);
holder.twtdt = (TextView) convertView
.findViewById(R.id.created);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.twtdata.setOnTextLinkClickListener(this);
holder.twtdata.gatherLinksForText(timelines[position]);
holder.twtdata.setTextColor(Color.BLACK);
holder.twtdata.setLinkTextColor(Color.BLUE);
MovementMethod m = holder.twtdata.getMovementMethod();
if ((m == null) || !(m instanceof LinkMovementMethod)) {
if (holder.twtdata.getLinksClickable()) {
holder.twtdata.setMovementMethod(LinkMovementMethod.getInstance());
}
}
if (bmpimg1[position] != null)
holder.twtimg.setImageBitmap(bmpimg1[position]);
holder.twtnm.setText(twitterhandles[position]);
Date credate = new Date(created[position]);
String dt = credate.getDate() + " "
+ getMonthName(credate.getMonth());
holder.twtdt.setText(dt);
holder.twtdata.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
pos = position;
if(linkselected==true)
return;
childSelected = true;
Log.i("mention data", timelines[position]);
Intent textintent = new Intent(ctx, TimelineRe.class);
textintent.putExtra("userid", userid[position]);
textintent.putExtra("nm", twitterhandles[position]);
textintent.putExtra("msg", timelines[position]);
textintent.putExtra("pos", position);
textintent.putExtra("frm", "t");
textintent.putExtra("img", bmpimg1[position]);
if (urlentities[position] != null
&& dpurlentities[position] != null) {
textintent.putExtra("urlentity", urlentities[position]);
textintent.putExtra("dpurlentity", dpurlentities[position]);
}
textintent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
ctx.startActivity(textintent);
}
});
holder.twtnm.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
childSelected = true;
Intent iconintent = new Intent(ctx, TweetRe.class);
iconintent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
iconintent.putExtra("userid", userid[position]);
iconintent.putExtra("pos", position);
iconintent.putExtra("frm", "t");
iconintent.putExtra("img", bmpimg1[position]);
ctx.startActivity(iconintent);
}
});
holder.twtimg.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
childSelected = true;
Intent iconintent = new Intent(ctx, TweetRe.class);
iconintent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
iconintent.putExtra("userid", userid[position]);
iconintent.putExtra("pos", position);
iconintent.putExtra("frm", "t");
iconintent.putExtra("img", bmpimg1[position]);
ctx.startActivity(iconintent);
}
});
return convertView;
}
@Override
public int getItemViewType(int position) {
return position;
}
@Override
public int getViewTypeCount() {
return timelines.length;
}
static class ViewHolder {
TextView twtdt;
LinkEnabledTextView twtdata;
ImageView twtimg;
TextView twtnm;
}
public void onTextLinkClick(View textView, String clickedString)
{
if (isWiFiConnected == false) {
Toast.makeText(ctx,
"No Internet Connection \nPlease Check and Retry",
Toast.LENGTH_SHORT).show();
return;
}
android.util.Log.v("Hyperlink clicked is :: " + clickedString, "Hyperlink clicked is :: " + clickedString);
if(clickedString.charAt(0)=='#')
{
linkselected=true;
childSelected=true;
Intent reintent = new Intent(ctx,
Search.class);
reintent.putExtra("frm", "l");
reintent.putExtra("keyword",clickedString.substring(1, clickedString.length()) );
reintent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
ctx.startActivity(reintent);
}
else if(clickedString.charAt(0)=='@')
{
linkselected=true;
childSelected=true;
Intent iconintent = new Intent(ctx, TweetRe.class);
iconintent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
iconintent.putExtra("snm", clickedString.substring(1,clickedString.length()));
iconintent.putExtra("frm", "l");
// iconintent.putExtra("userid", userid[pos]);
// iconintent.putExtra("pos", pos);
// iconintent.putExtra("img", bmpimg2[pos]);
ctx.startActivity(iconintent);
}
else if(clickedString.charAt(0)=='h')
{
linkselected=true;
childSelected=true;
Intent iconintent = new Intent(ctx, ShowLink.class);
iconintent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
iconintent.putExtra("url","http://www."+dpurlentities[pos]);
ctx.startActivity(iconintent);
}
}
}
text colors for one TextView using two Linkify's and weblinks clickable
Finally i have achieved hashtags weblinks clickable and made them very attractive by keeping different colors
using android sdk SpannableString and it's ClickableSpan .
private void Linkfiy(String a, TextView textView) {
Pattern urlPattern = Patterns.WEB_URL;
Pattern mentionPattern = Pattern.compile("(@[A-Za-z0-9_-]+)");
Pattern hashtagPattern = Pattern.compile("#(\\w+|\\W+)");
Matcher o = hashtagPattern.matcher(a);
Matcher mention = mentionPattern.matcher(a);
Matcher weblink = urlPattern.matcher(a);
SpannableString spannableString = new SpannableString(a);
//#hashtags
while (o.find()) {
spannableString.setSpan(new NonUnderlinedClickableSpan(o.group(),
0), o.start(), o.end(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
// --- @mention
while (mention.find()) {
spannableString.setSpan(
new NonUnderlinedClickableSpan(mention.group(), 1), mention.start(), mention.end(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
//@weblink
while (weblink.find()) {
spannableString.setSpan(
new NonUnderlinedClickableSpan(weblink.group(), 2), weblink.start(), weblink.end(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
textView.setText(spannableString);
textView.setMovementMethod(LinkMovementMethod.getInstance());
}
NonUnderlinedClickableSpan class
public class NonUnderlinedClickableSpan extends ClickableSpan {
int type;// 0-hashtag , 1- mention, 2- url link
String text;// Keyword or url
String time;
public NonUnderlinedClickableSpan(String text, int type) {
this.text = text;
this.type = type;
this.time = time;
}
@Override
public void updateDrawState(TextPaint ds) {
//adding colors
if (type == 1)
ds.setColor(InstagramIndetail.this.getResources().getColor(
R.color.link_color_mention));
else if (type == 2)
ds.setColor(InstagramIndetail.this.getResources().getColor(
R.color.link_color_url));
else
ds.setColor(InstagramIndetail.this.getResources().getColor(
R.color.link_color_hashtag));
ds.setUnderlineText(false);
// ds.setTypeface(Typeface.DEFAULT_BOLD);
}
@Override
public void onClick(View v) {
Debug.e("click done", "ok " + text);
if (type == 0) {
//pass hashtags to activity using intents
} else if (type == 1) {
//do for mentions
} else {
// passing weblinks urls to webview activity
startWebViewActivity(text);
}
}
}
Android: multiple textview like a single text
you can use FlowLayout if you really need this. But if you can, you should use one textView and format text using spannables.
How to implement a OnClick for a text/link which is in a TextView
You should use built-in linkify. Read this tutorial, easy to understand:
Linkify text link url in TextView text Android example
These post also may help you Android Linkify text - Spannable Text in Single Text View - As like Twitter tweet
and Android: ClickableSpan in clickable TextView
And here is complete code using Spannable :
final String webAddress = "www.123456.org";
final String emailAddress = "info@123456.com";
TextView text = (TextView)findViewById(R.id.textview);
Spannable span = Spannable.Factory.getInstance().newSpannable("For more details on the app visit us at " + webAddress + " or write to us at " + emailAddress);
ClickableSpan webClickSpan = new ClickableSpan() {
@Override
public void onClick(View v) {
Uri uriUrl = Uri.parse("http://" + webAddress);
Intent launchBrowser = new Intent(Intent.ACTION_VIEW, uriUrl);
startActivity(launchBrowser);
} };
ClickableSpan emailClickSpan = new ClickableSpan() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("message/rfc822");
intent.putExtra(Intent.EXTRA_EMAIL, new String[]{emailAddress});
intent.putExtra(Intent.EXTRA_SUBJECT, "Subject");
intent.putExtra(Intent.EXTRA_TEXT, "email body.");
startActivity(Intent.createChooser(intent, "Send Email"));
} };
span.setSpan(webClickSpan, 40, 40 + webAddress.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
span.setSpan(emailClickSpan, 73, span.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
text.setText(span);
text.setMovementMethod(LinkMovementMethod.getInstance());
Related Topics
Is Google's Android Opengl Tutorial Teaching Incorrect Linear Algebra
Android Copy/Paste from Clipboard Manager
Find Out the Running Process Id by Package Name
How to Retrieve the Data from Asynctasks Doinbackground()
Animation in Notification Bar Custom View
How to Disable All Views Inside the Layout
Difference Between Content_Main.Xml and Activity_Main.Xml
Android App Crashes with Sigabrt Signal 6 Only While Eclipse Debugging
If I Call Getmeasuredwidth() or Getwidth() for Layout in Onresume They Return 0
How to Get File Path from Sd Card in Android
Android Overlay to Grab All Touch, and Pass Them On
Uncaught Exception in Firebase Runloop (3.0.0)
Opening Webview Not in New Browser
How to Get HTML Source Code from Url in Android