Consider the sentence
"Mike has commented on Davids review at Pizza Planet"
This sentence may wrap onto 2 lines, but I want the words "Mike", "Davids" and "Pizza Planet clickable items".
If I use separate TextViews for each of these word, and also for the non clickable words in between, How can I do this so that they wrap nicely onto 2 lines?
You can use spannable strings for your needs, check this out:
TextView textView = (TextView) findViewById(R.id.textView);
SpannableString user = new SpannableString("Mike");
ClickableSpan userClickableSpan = new ClickableSpan() {
#Override
public void onClick(View textView) {
//click on user
}
};
user.setSpan(userClickableSpan, 0, user.length(),
SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE);
SpannableString commentedOnUser = new SpannableString("Davids");
ClickableSpan commentedOnUserClickableSpan = new ClickableSpan() {
#Override
public void onClick(View textView) {
//click on commentedOnUser
}
};
commentedOnUser.setSpan(commentedOnUserClickableSpan, 0, commentedOnUser.length(),
SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE);
SpannableString place = new SpannableString("Pizza Planet");
ClickableSpan placeClickableSpan = new ClickableSpan() {
#Override
public void onClick(View textView) {
//click on place
}
};
place.setSpan(placeClickableSpan, 0, place.length(),
SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setMovementMethod(LinkMovementMethod.getInstance());
textView.setHighlightColor(Color.TRANSPARENT);
textView.setText(user);
textView.append(" is has commented on ");
textView.append(commentedOnUser);
textView.append(" review at ");
textView.append(place);
Now when it's all part of one TextView, use "\n" to break the line.
Related
Good afternoon. Could you help me with a clickable span? The fact is that when I assign a clickable substring at the end of an origin String, not only the text becomes clickable, but also the entire TextView area to the right of the substring, which is bad for me (it is necessary that only a substring is clickable. Can you advise me something ? match parent for my textview is required. Unfortunately, programmatically adding " " to the original string is also unacceptable to me. Pastebin link with code: here. I created a video on my Dropbox:
bad work my programm:
dropbox
I want it to work like this
dropbox
My TextView needs the following layout
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
my code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = findViewById(R.id.text_view);
SpannableString spanable = new SpannableString("my clickable span");
ClickableSpan clickableSpan = new ClickableSpan() {
#Override
public void onClick(View widget) {
Toast.makeText(MainActivity.this, "click span", Toast.LENGTH_SHORT).show();
}
};
spanable.setSpan(clickableSpan, 13, 17, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
textView.setText(spanable);
textView.setMovementMethod(LinkMovementMethod.getInstance());
}
set all text using length.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = findViewById(R.id.text_view);
String strService = "my clickable span";
int serviceStart = strService.indexOf("my clickable span");
int serviceEnd = serviceStart + "my clickable span".length();
SpannableString spanable = new SpannableString(strService);
ClickableSpan clickableSpan = new ClickableSpan() {
#Override
public void onClick(View widget) {
Toast.makeText(MainActivity.this, "click span", Toast.LENGTH_SHORT).show();
}
};
spanable.setSpan(clickableSpan, serviceStart, serviceEnd, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
textView.setText(spanable);
textView.setClickable(true); //add clickable
textView.setMovementMethod(LinkMovementMethod.getInstance());
}
I want make a layout like this .
Initially we arranged buttons and text in succession.
However, if there is a line break, it will not be displayed as desired.
Do you know the library or the means to realize this?
My English is still not so good, though, Sorry.
String str="text1 button1 text2 button2 etc.";
SpannableString spanString=new SpannableString(str);
//You can use SpannableStringBuilder also
ClickableSpan buttonSpan1 = new ClickableSpan() {
#Override
public void onClick(View view) {
// Do something
}
};
ClickableSpan buttonSpan2 = new ClickableSpan() {
#Override
public void onClick(View view) {
// Do something
}
};
spanString.setSpan(
buttonSpan1,
str.indexOf("button1"),
str.indexOf("button1") + String.valueOf("button1").length(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spanString.setSpan(
buttonSpan2,
str.indexOf("button2"),
str.indexOf("button2") + String.valueOf("button2").length(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
I have a string in database that is like:
string f = "this is the first link and this is the second link"
textview1.TextFormatted = Html.FromHtml(f);
url =?
Intent i = new Intent(Android.Content.Intent.ActionView,url);
StartActivity(i);
the number of links in the string is different. I want to make all link in textview clickable and when user click on each of them, the url of that link send to another activity.
When you setText using Html.fromHtml, the '' are replaced as UrlSpans in textView.
You can get each of url spans and set clickable spans for onClick function.
Refer to this for the solution code.
I have achieved the same using SpannableStringBuilder.
Simply initialize the TextView that you want to add 2 or more listeners and then pass that to the following method that I have created:
private void customTextView(TextView view) {
SpannableStringBuilder spanTxt = new SpannableStringBuilder(
getString(R.string.read_and_accept));
spanTxt.setSpan(new ForegroundColorSpan(ContextCompat.getColor(activity, R.color.black_30)), 0,
getString(R.string.read_and_accept).length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
spanTxt.append(" ");
spanTxt.append(getString(R.string.t_and_c));
spanTxt.setSpan(new ClickableSpan() {
#Override
public void onClick(View widget) {
Utils.redirectUserToUrl(activity,"http://luxit-driver-terms.tookan.in");
}
}, spanTxt.length() - getString(R.string.t_and_c).length(), spanTxt.length(), 0);
spanTxt.append(" and ");
spanTxt.setSpan(new ForegroundColorSpan(ContextCompat.getColor(activity, R.color.accent)), 48, spanTxt.length(), 0);
spanTxt.append(getString(R.string.privacy_policy));
spanTxt.setSpan(new ClickableSpan() {
#Override
public void onClick(View widget) {
Utils.redirectUserToUrl(activity,"http://luxit-driver-privacypolicy.tookan.in/");
}
}, spanTxt.length() - getString(R.string.privacy_policy).length(), spanTxt.length(), 0);
view.setMovementMethod(LinkMovementMethod.getInstance());
view.setText(spanTxt, TextView.BufferType.SPANNABLE);
}
In Xml,use android:textColorLink to add custom color for ur link text
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="text"
android:textColorLink="#000000" />
I used Android.text.style.ClickableSpan to make a part (Black) of a string (Blue | Black) clickable:
SpannableString spannableString = new SpannableString("Blue | Black ");
ClickableSpan clickableSpan = new ClickableSpan() {
#Override
public void onClick(View textView) {
//...
}
};
ss.setSpan(clickableSpan, 7, 11, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
TextView textView = (TextView) findViewById(R.id.secondActivity_textView4);
textView.setText(spannableString);
textView.setMovementMethod(LinkMovementMethod.getInstance());
So Black part of the string is clickable. What I want is that when the user clicks Black, it should make Black Not-clickable, and Blue (another part of the same string) clickable.
So to make Blue clickable, we can call setSpan() on the same spannableString another time. But how can I make Black not-clickable?
You can call removeSpan() to remove any previously added Spans. In this particular case it's very easy, as we hold a reference to the very Span we want to remove:
ClickableSpan clickableSpan = new ClickableSpan()
{
#Override
public void onClick(View view)
{
((SpannableString)textView.getText()).removeSpan(this);
}
};
Another option could be to iterate over all ClickableSpan instances and remove them all, such as:
SpannableString str = (SpannableString)textView.getText();
for (ClickableSpan span : str.getSpans(0, str.length(), ClickableSpan.class))
str.removeSpan(span);
For some reason that I cannot fathom, the documentation for spans is really poor... they are quite powerful!
I've been using the android:autoLink just fine for formatting links and such, but I need to use android:onClick so I can't use that in this case. The reasoning is that I find it too easy to click on a phone number accidentally, so I'm going to intercept the click with a confirmation Dialog and then call.
Is there an easy way to still make the phone number in my TextView look like a normal clickable link? I poked around the Android source code, but couldn't find any particular style for me to reference.
This is the shortest solution:
final CharSequence text = tv.getText();
final SpannableString spannableString = new SpannableString( text );
spannableString.setSpan(new URLSpan(""), 0, spannableString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
tv.setText(spannableString, TextView.BufferType.SPANNABLE);
Sadly, the effect of clicking doesn't show up as being clicked on a real url link, but you can overcome it like so:
final CharSequence text = tv.getText();
final SpannableString notClickedString = new SpannableString(text);
notClickedString.setSpan(new URLSpan(""), 0, notClickedString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
tv.setText(notClickedString, TextView.BufferType.SPANNABLE);
final SpannableString clickedString = new SpannableString(notClickedString);
clickedString.setSpan(new BackgroundColorSpan(Color.GRAY), 0, notClickedString.length(),
Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
tv.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(final View v, final MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
tv.setText(clickedString);
break;
case MotionEvent.ACTION_UP:
tv.setText(notClickedString, TextView.BufferType.SPANNABLE);
v.performClick();
break;
case MotionEvent.ACTION_CANCEL:
tv.setText(notClickedString, TextView.BufferType.SPANNABLE);
break;
}
return true;
}
});
Another solution is to use Html.fromHtml(...) , where the text inside has links tags ("") .
If you wish for another solution, check this post.
You can create a colors.xml resource file, what contains colors. Please take a look at Colors
If you want to underline your text, then please take a look at this post:
Underline
Don't forget to add android:clickable="true" or setClickable(true) to
your TextViews to make them clickable!
Linkify is a great class, it hunts for complex patterns like URLs, phone numbers, etc and turns them into URLSpans. Rather than re-write the existing regular expressions I extended the URLSpan class and created a method to upgrade only the telephone URLSpans to a custom URLSpan with a confirmation dialog.
First my extended URLSpan class, ConfirmSpan:
class ConfirmSpan extends URLSpan {
AlertDialog dialog;
View mView;
public ConfirmSpan(URLSpan span) {
super(span.getURL());
}
#Override
public void onClick(View widget) {
mView = widget;
if(dialog == null) {
AlertDialog.Builder mBuilder = new AlertDialog.Builder(widget.getContext());
mBuilder.setMessage("Do you want to call: " + getURL().substring(4) + "?");
mBuilder.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
})
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
openURL();
}
});
dialog = mBuilder.create();
}
dialog.show();
}
public void openURL() {
super.onClick(mView);
}
}
Next the method to swap out the different span classes:
private void swapSpans(TextView textView) {
Spannable spannable = (Spannable) textView.getText();
URLSpan[] spans = textView.getUrls();
for(URLSpan span : spans) {
if(span.getURL().toString().startsWith("tel:")) {
spannable.setSpan(new ConfirmSpan(span), spannable.getSpanStart(span), spannable.getSpanEnd(span), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
spannable.removeSpan(span);
}
}
}
Finally all you need to do is create a TextView with the autoLink attribute:
android:autoLink="phone"
And remember to call the swapSpans() method. Understand that I wrote this for fun, there may be other methods of doing this but I am unaware of them at the moment. Hope this helps!
To underline your TextView's text, you have to do something like:
final TextView text = (TextView) findViewById(R.id.text);
SpannableString string = new SpannableString("This is the uderlined text.");
string.setSpan(new UnderlineSpan(), 0, string.length(), 0);
text.setText(string);
This should work. Let me know about your progress.
With kotlin extension function (if you don't need the click effect as on a real link)
fun TextView.hyperlinkStyle() {
setText(
SpannableString(text).apply {
setSpan(
URLSpan(""),
0,
length,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
)
},
TextView.BufferType.SPANNABLE
)
}
How to use
yourTextView.hyperlinkStyle()
Have a better answer.This is what i did.
final SpannableString ss = new SpannableString("Click here to verify Benificiary");
ClickableSpan clickableSpan = new ClickableSpan() {
#Override
public void onClick(View textView) {
}
#Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
}
};
ss.setSpan(clickableSpan,0,ss.length(),Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setMovementMethod(LinkMovementMethod.getInstance());
textView.setHighlightColor(Color.BLUE);
You go anywhere you like when user clicks on the link through onclick method of ClickableSpan
Simply underline it:
val myText = "Text to be underlined"
textView.text = Html.fromHtml("<u>$myText</u>")
or with kotlin extensions:
fun TextView.underline() {
text = Html.fromHtml("<u>${text}</u>")
}
usage:
textView.text = myText
textView.underline()
More ways to style text in android here: https://medium.com/androiddevelopers/spantastic-text-styling-with-spans-17b0c16b4568