I'm trying to achieve something like this image image twitter tweet. The user creates tweets with hash tags and links in it and Twitter app converts into click able links. Normal TextView can't achieve that. How do I create something like that? Please provide technical details.
Try this
You can use ClickableSpan to achieve this like this
ClickableSpan clickableSpan = new ClickableSpan() {
#Override
public void onClick(View textView) {
Toast.makeText(context,"clicked", Toast.LENGTH_SHORT).show();
}
};
SpannableStringBuilder builder = new SpannableStringBuilder();
SpannableString str1 = new SpannableString("click me");
str1.setSpan(clickableSpan, 0, str1.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
str1.setSpan(new ForegroundColorSpan(Color.BLUE), 0, str1.length(), 0);
str1.setSpan(new UnderlineSpan(), 0, str1.length(), 0);
SpannableString str2 = new SpannableString("demo String 2 ");
builder.append(str2);
builder.append(str1);
Textview.setText(builder, TextView.BufferType.SPANNABLE);
Textview.setMovementMethod(LinkMovementMethod.getInstance());
Related
I have a TextView that displays texts retrieved from db and some parts of the texts are marked as comment.
Here is sample.....
// CREATE A VARIABLE AT THE CLASS LIKE THIS...
private static int delay = 4000; //4Secs
/*NOW THE DELAY METHOD*/
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// DECLARE ACTIONS TO BE DELAYED HERE...
}
}, delay);
Now i want all the single and multi line comment texts to have a different textColor. How do i go about this?
If you format the String with html's font-color property then pass it to the method Html.fromHtml(your text here)
String text = "<font color=#cc0029>First Color</font> <font color=#ffcc00>Second Color</font>";
yourtextview.setText(Html.fromHtml(text));
or You can prints lines with multiple colors without HTML as:
SpannableStringBuilder builder = new SpannableStringBuilder();
SpannableString str1= new SpannableString("Text1");
str1.setSpan(new ForegroundColorSpan(Color.RED), 0, str1.length(), 0);
builder.append(str1);
SpannableString str2= new SpannableString("Text2");
str2.setSpan(new ForegroundColorSpan(Color.GREEN), 0, str2.length(), 0);
builder.append(str2);
TextView tv = (TextView) view.findViewById(android.R.id.text1);
tv.setText( builder, TextView.BufferType.SPANNABLE);
I tried URLSpan in scannable string like this
private void setSmsText() {
SpannableString string = new SpannableString("Text with a url span");
string.setSpan(new URLSpan("http://www.developer.android.com"), 12, 15, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
sms_text.setText(string);
sms_text.setMovementMethod(LinkMovementMethod.getInstance());
}
Here while commenting the setMovementMethod line the text appears to be clickable(url format)
but when uncommenting the text is not clickable
I am not able to navigate to the url by clicking on the text
Try this
SpannableString spannableString = new SpannableString(YOUR_TEXT);
ClickableSpan clickableSpan = new ClickableSpan() {
#Override
public void onClick(View widget) {
//your code like open webview or any other
}
};
spannableString.setSpan(clickableSpan, YOUR_TEXT_STARTING_INDEX,YOUR_TEXT_END_INDEX , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
let me know if this work or not
I want to show the spanString in Bold style and rest of the string in normal style in TextView. But the whole TextView showed in normal style only. Please help me.
if ((mStoreListValue.get(pos).getStoreStatus().equals("CLOSED"))){
final Dialog dialog = new Dialog(v.getRootView().getContext(), android.R.style.Theme_Translucent_NoTitleBar);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.getWindow().setContentView(R.layout.resclosed_dialog);
ImageView btn_close = dialog.findViewById(R.id.close_btn);
TextView txt_close = dialog.findViewById(R.id.tv_closed);
SpannableString spanString = new SpannableString(sname);
spanString.setSpan(new StyleSpan(Typeface.BOLD), 0, spanString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
txt_close.setText(spanString + " " + mContext.getResources().getString(R.string.closed));
btn_close.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
dialog.dismiss();
}
});
dialog.show();
Thats because you just concat SpannableString with String which will be result as toString()(a Normal String with hash code of object). Use a single String with multiple Span.
See the following example.
String s1="My app";
String s2= "Close";
SpannableString spanString = new SpannableString(s1+s2);
spanString.setSpan(new StyleSpan(Typeface.BOLD), 0, s1.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spanString.setSpan(new StyleSpan(Typeface.NORMAL), s1.length(), (s1+s2).length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spanString);
Use this
SpannableStringBuilder builder = new SpannableStringBuilder();
SpannableString spanString = new SpannableString(sname);
spanString.setSpan(new StyleSpan(Typeface.BOLD), 0, spanString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
builder.append(spanString);
builder.append(mContext.getResources().getString(R.string.closed));
txt_close.setText(builder);
Instead of this
txt_close.setText(spanString + " " + mContext.getResources().getString(R.string.closed));
Using String templating, you can have a string resource:
<b> indicates bold,
%1$d indicates I am expecting a digit/number
so I get (5 min away) in the textview
//xml
<string name="confirm_eta_text"> <b>%1$d min </b> away</string>
// Java
mEta.setText(
Compat.fromHtml(String.format(getResources().getString(R.string.confirm_eta_text), 5)));
Android String Formatting
I have a textview as like the following:
txtByRegistering.setText("By Registering you agree to terms and condition and privacy policy");
It is just a big text. So, I used marquee to scroll the text horizontally. that works fine. My Question is, How to invoke the click event while clicking the selected scrolling text .
Say for ex :
when user click the word "Registering" in the above textview, I have to invoke the new Intent.
When the user click on the word "Terms" , I have to
invoke another new Intent (An Activity with webview as Terms has URL Link).
As the word "Registering" and "Terms" are Web URLs, I tried something like below :
String mRegDesc = "By registering you agree to the " + "<a href=\""
+ Constant.URL + "/terms_and_conditions"
+ "\">Terms of Use</a> " + "and " + "<a href=\"" + Constant.URL
+ "/privacy" + "\">Privacy Policy</a> ";
txtByRegistering.setText(Html.fromHtml(mRegDesc));
txtByRegistering.setMovementMethod(LinkMovementMethod.getInstance());
txtByRegistering.setSelected(true);
txtByRegistering.setTypeface(mTyFaceOverLockReg, Typeface.BOLD);
The above code works fine and it brings me to the browser when i click the word "Terms" But i wish to go to new Activity.
Finally,
I found the solution for that,
Here is the solution :
SpannableString SpanString = new SpannableString(
"By Registering you agree to the Terms of Use and Privacy Policy");
ClickableSpan teremsAndCondition = new ClickableSpan() {
#Override
public void onClick(View textView) {
Intent mIntent = new Intent(SignUp.this, CommonWebView.class);
mIntent.putExtra("isTermsAndCondition", true);
startActivity(mIntent);
}
};
// Character starting from 32 - 45 is Terms and condition.
// Character starting from 49 - 63 is privacy policy.
ClickableSpan privacy = new ClickableSpan() {
#Override
public void onClick(View textView) {
Intent mIntent = new Intent(SignUp.this, CommonWebView.class);
mIntent.putExtra("isPrivacyPolicy", true);
startActivity(mIntent);
}
};
SpanString.setSpan(teremsAndCondition, 32, 45, 0);
SpanString.setSpan(privacy, 49, 63, 0);
SpanString.setSpan(new ForegroundColorSpan(Color.BLUE), 32, 45, 0);
SpanString.setSpan(new ForegroundColorSpan(Color.BLUE), 49, 63, 0);
SpanString.setSpan(new UnderlineSpan(), 32, 45, 0);
SpanString.setSpan(new UnderlineSpan(), 49, 63, 0);
txtByRegistering.setMovementMethod(LinkMovementMethod.getInstance());
txtByRegistering.setText(SpanString, BufferType.SPANNABLE);
txtByRegistering.setSelected(true);
thanks to Shayan pourvatan.
Let assume here is your complete string
By Signing up, I agree to Terms of Conditions & Privacy Policy
and string you want to make clickable is
Terms of Conditions and Privacy Policy
so, here is my trick.....
ClickableSpan terms = new ClickableSpan() {
#Override
public void onClick(View widget) {
new Utils(getActivity()).shortToast("Terms");
}
};
ClickableSpan privacy = new ClickableSpan() {
#Override
public void onClick(View widget) {
new Utils(getActivity()).shortToast("Privacy");
}
};
the main function for this
public void setClickableString(String wholeValue, TextView textView, final String[] clickableValue, ClickableSpan[] clickableSpans) {
SpannableString spannableString = new SpannableString(wholeValue);
for (int i = 0; i < clickableValue.length; i++) {
ClickableSpan clickableSpan = clickableSpans[i];
String link = clickableValue[i];
int startIndexOfLink = wholeValue.indexOf(link);
spannableString.setSpan(clickableSpan, startIndexOfLink, startIndexOfLink + link.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
textView.setHighlightColor(
Color.TRANSPARENT); // prevent TextView change background when highlight
textView.setMovementMethod(LinkMovementMethod.getInstance());
textView.setText(spannableString, TextView.BufferType.SPANNABLE);
}
and here is the function calling
setClickableString(getString(R.string.terms_and_policy), tv_terms, new String[]{"Terms of Conditions", "Privacy Policy"}, new ClickableSpan[]{terms, privacy});
Use this one it works for me two click in single TextView
Step1-: Your text will be in SpannableString
SpannableString ss = new SpannableString("By Registering you agree to terms and condition and privacy policy");
Step2:-add click in ClickableSpan like this
ClickableSpan Registering = new ClickableSpan() {
#Override
public void onClick(View textView) {
Intent intent=new Intent(this,WebView_Activity.class);
startActivity(intent);
}
#Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(true);
}
};
ClickableSpan terms = new ClickableSpan() {
#Override
public void onClick(View textView) {
Intent intent=new Intent(this,WebView_Activity.class);
startActivity(intent);
}
#Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(true);
}
};
Final step add your click on SpannableString with character starting and ending index like Registering word in start at 3rd position and end at 11 so add click for Registering word
ss.setSpan(Registering , 3, 11, 0);
same for term after this add your SpannableString on your TextView
textview.setMovementMethod(LinkMovementMethod.getInstance());
textview.setText(ss, TextView.BufferType.SPANNABLE);
textview.setSelected(true);
I would suggest below code for clickable string in TextView it is dynamic.
Advantage of this code is if you have same String multiple times you can have click on both Strings. For example if you want to set click and String is Boy is playing cricket. Boy is playing football. Boy is two times both word will be clickable.
public void setClicksOnString(String completeString, List<String> stringsToClick, TextView textView) {
SpannableString spannableString = new SpannableString(completeString);
for (int m = 0; m < stringsToClick.size(); m++) {
Matcher matcher = Pattern.compile(stringsToClick.get(m)).matcher(spannableString);
while (matcher.find()) {
ClickableSpan stringClick = new ClickableSpan() {
#Override
public void onClick(View widget) {
//you compare the string and your click logics
}
};
spannableString.setSpan(stringClick, matcher.start(), matcher.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
textView.setHighlightColor(
Color.TRANSPARENT); // prevent TextView change background when highlight
textView.setMovementMethod(LinkMovementMethod.getInstance());
textView.setText(spannableString, TextView.BufferType.SPANNABLE);
}
In addition, if you want to know in which text the user clicked dynamically, use below
ClickableSpan listener = new ClickableSpan() {
#Override
public void onClick(View textView) {
TextView tv = (TextView) textView;
Spanned s = (Spanned) tv.getText();
int start = s.getSpanStart(this);
int end = s.getSpanEnd(this);
String clickedText = s.toString().substring(start,end);
}
};
I am following this example in using SpannableString:
http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/text/Link.html
I am trying to create a string which has 'R.string.text1' following by R.string.text2 but R.string.text2 (has 10 characters) in URL format:
SpannableString ss = new SpannableString(getString(R.string.text1));
ss.setSpan(new URLSpan(getString(R.string.text2)), 0, 10, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
But what I am getting is
I don't see the string R.string.text2 at all
and only the first 10 characters is in URL format
How can I fix my problem?
This is a more general answer to show just a basic working example of a URLSpan.
// set up spanned string with url
SpannableString spannableString = new SpannableString("Click here for more.");
String url = "https://developer.android.com";
spannableString.setSpan(new URLSpan(url), 6, 10, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// set to textview
textView.setText(spannableString);
textView.setMovementMethod(LinkMovementMethod.getInstance()); // enable clicking on url span
May i correct you ?
SpannableString ss = new SpannableString(getText(R.string.text1)+" "+getText(R.string.text2));
ss.setSpan(new URLSpan(getString(R.string.text2)),
getString(R.string.text1).length()+1,
ss.length(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
quite late, but at least done for the others ^^
you can also do it this way :
SpannableString ss1 = new SpannableString(getText(R.string.text1));
// do what you want with ss1
SpannableString ss2 = new SpannableString(getText(R.string.text2)); // the text visible
ss2.setSpan(new URLSpan(getString(R.string.text2)), // this is the link itself
0,
ss2.length(), // link on entire text
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
CharSequence csSS = TextUtils.concat(ss1, ss2); // import android.text.TextUtils;
try this way..
SpannableString ss = new SpannableString(getString(R.string.text1+""+R.string.text2));
ss.setSpan(new URLSpan(getString(R.string.text2)), 0, getString(R.string.text2).length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
In the kotlin, you can use like this way
fun SpannableStringBuilder.urlSpan(value: String): SpannableStringBuilder {
val start = length
this.append(value)
val end = length
this.setSpan(URLSpan(value), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
return this
}
SpannableStringBuilder().urlSpan("www.google.com")