I have to embed a clickable text in a paragraph text, clickablespan can do it. But instead of using the default focus/press/unfocus style, can I change those style ? Like when focus, the background color is blue, text color is white, when unfocus, the background color is white, text color is blue.
You can override the updateDrawState method of ClickableSpan:
SpannableString spannableString = new SpannableString("text");
spannableString.setSpan(
new ClickableSpan() {
#Override
public void onClick(View widget) {
Toast.makeText(getContext(), "Click!", Toast.LENGTH_LONG).show();
}
#Override
public void updateDrawState(TextPaint ds) {
ds.setColor(getResources().getColor(R.color.link));
}
}, 0, 4, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
textView.setText(spannableString);
textView.setMovementMethod(LinkMovementMethod.getInstance());
Here is the example
bottomMsg = (TextView) findViewById(R.id.bottom_msg);
int start = bottomMsg.getText().toString().indexOf(terms);
MovementMethod movementMethod = LinkMovementMethod.getInstance();
bottomMsg.setMovementMethod(movementMethod);
Spannable text = (Spannable) bottomMsg.getText();
//TermAndConditions is a clickableSpan.
text.setSpan(new TermAndConditions(), start, start + terms.length(), Spannable.SPAN_POINT_MARK);
text.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.customYellowColor)), start, start + terms.length(), 0);
The point is, color-span is after the clickable-span. otherwise, the color not changed.
Link color can be changed in xml:
<TextView
android:textColor="..."
android:textColorLink="..." />
Related
I am using TextView to display text. I need to display max 3 line of text. To accomplish this , i have used maxLines property.
<TextView
android:id="#+id/textFeedText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="3"
android:textColor="#color/colorFeedDate"
android:textSize="#dimen/d13sp"/>
Now i need to set sppannable text in textview. Following is my code to set clickable span.
SpannableString spannableString = new SpannableString(requiredString);
ClickableSpan clickSpan = new ClickableSpan() {
#Override
public void onClick(View view) {
}
#Override
public void updateDrawState(TextPaint ds) {
ds.setColor(ContextCompat.getColor(mContext, R.color.colorAppBlue));
ds.setUnderlineText(false);
}
};
spannableString.setSpan(clickSpan, indexOfStart, indexOfEnd - 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.append(spannableString);
textView.setMovementMethod(LinkMovementMethod.getInstance());
It display okay. Now when i tap on textview then sometimes multiline property not seems working. Textview text scrolls vertically. And display following view.
Anyone has faced such issue?
Thanks.
The following code shows how I'm applying a pressed state using a custom ClickableSpan and selector. However, the pressed state is applied whenever I press anywhere on the TextView, not just the ClickableSpan. How do I stop this?
Note: it does not call onClick, but does apply state_pressed from the selector. I want it to do neither.
MyView.java
SpannableString spanned = new SpannableString("click here");
spannable.setSpan(new MyClickableSpan() {
#Override
public void onClick(View widget) {
doSomething();
}
}, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spanned);
textView.setMovementMethod(LinkMovementMethod.getInstance());
MyClickableSpan.java
public abstract class MyClickableSpan extends ClickableSpan {
#Override
public abstract void onClick(View view);
#Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
}
}
the TextView
<TextView
android:id="#+id/my_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#android:color/white"
android:textColorLink="#color/my_selector" />
my_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:color="#color/my_color_pressed" />
<item android:color="#color/my_color" />
</selector>
Edit note: Added TextView code
Next example works as you're expecting:
Spannable span = SpannableStringBuilder.valueOf("Hello clickable span!");
span.setSpan(new MyClickableSpan(), 6, 15, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
mTextView.setText(span);
mTextView.setMovementMethod(LinkMovementMethod.getInstance());
Now span applied:
Here's MyClickableSpan() that's only show Snackbar to indicate that "click" is handled:
class MyClickableSpan extends ClickableSpan {
#Override
public void onClick(View widget) {
Snackbar.make(getWindow().findViewById(android.R.id.content), "Click on span!", Snackbar.LENGTH_LONG).show();
}
}
We've got:
Click/tap outside the "spanned" text will do nothing
Click/tap on "spanned" part of text will show Snackbar
That's it. Please let me know if you need any additional info.
You have to set MovementMethod to the TextView which has the Span.
textView.setMovementMethod(LinkMovementMethod.getInstance());
You can refer below code I have tested it.
String s = "This is custom string click Here";
SpannableString spanned = new SpannableString(s);
spanned.setSpan(new MyClickableSpan() {
#Override
public void onClick(View widget) {
Log.i("main", "Link clicked");
}
}, s.length() - 10, s.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spanned);
textView.setMovementMethod(LinkMovementMethod.getInstance());
TextView
<TextView
android:id="#+id/my_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#drawable/my_selector"
android:textColorLink="#color/colorPrimary" />
You can use tutorial here
In your code you have define
android:textColor="#android:color/white"
instead of this you have to define your selector like below
android:textColor="#drawable/my_selector"
rest of code is as it is you have to changed only one line that android:textColor="#drawable/my_selector" that i explain above.
You can do this way:
TextView textView = (TextView)findViewById(R.id.textView);
Spannable span = Spannable.Factory.getInstance().newSpannable("test link span");
span.setSpan(new ClickableSpan() {
#Override
public void onClick(View v) {
Log.i("main", "Link clicked");
Toast.makeText(HomeScreenActivity.this, "link clicked", Toast.LENGTH_SHORT).show();
} }, 5, 9, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// set the "test " spannable.
span.setSpan(cs, 0, 5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// set the " span" spannable
span.setSpan(cs, 6, span.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(span);
textView.setMovementMethod(LinkMovementMethod.getInstance());
Hope this will help you.
I just want to make some text clickable in TextView, so I used ClickableSpan, but the background color of text is changed when I touched it.
This is my code:
ClickableSpan clickableSpan = new ClickableSpan() {
#Override
public void onClick(View widget) {
// do something
}
};
SpannableString ss = new SpannableString("ClickableSpan Test");
ss.setSpan(clickableSpan, 0, 13, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
How can I prevent changing background color on touch?
Add this in you textview
android:textColorHighlight`="#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