I've been stuck at this problem for long. What I'm having is a simple string "This is a link and this is another link"
. I want to have both "link" words click-able, having different URLs to open in browser.
"This is a cat link and this is another cat link"
. Here I have to link both "cat" and "link" words with different URLs via Click-able Span. How do I go about it?Try in this manner
String s="Cat link 1 Cat link 2 Cat link 3";
SpannableString ss = new SpannableString(s);
String first ="Cat link 1";
String second ="Cat link 2";
String third ="Cat link 3";
int firstIndex = s.toString().indexOf(first);
int secondIndex = s.toString().indexOf(second);
ClickableSpan firstwordClick = new ClickableSpan() {
@Override
public void onClick(View widget) {
///............
}
};
ClickableSpan secondwordClick = new ClickableSpan() {
@Override
public void onClick(View widget) {
///............
}
};
ss.setSpan(firstwordClick,firstIndex, firstIndex+first.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
ss.setSpan(secondwordClick,secondIndex, secondIndex+second.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setLinksClickable(true);
textView.setMovementMethod(LinkMovementMethod.getInstance());
textView.setText(ss,BufferType.SPANNABLE);
If you cannot programmatically find the difference in the links, then you cannot expect anything else to be able to do it. As the developer, you need a system.
You need to be able to identify the clickable spans - since the links are unique, the text that identifies them must also be unique. This would be a problem for your users, most likely.
You can get an ordered list of URLs and then if the links are indistinguishable, simply use them in the order you receive. Or, you need to change the rules of creating the links or the order in which they are displayed.
One simple way to do this would be to include an identifier before the link say /*/
then using this find the start and end position for link. Once you have that first replace the identifier with a ""
and then click away.
I have string something such "you order with orderId {b1j2gh4b} has been claimed by bla bla sotre with phone number (1234124124)"
I am using these braces so as to find out the index of of orderID and Phone number
String notificationMessage = mArrListNotification.get(position).getMessage();
boolean isPhoneNumberAvailable = false, isOrderIdAvailable = false;
int phoneStartIndex = 0, phoneEndIndex = 0, orderIdStartIndex = 0, orderIdEndIndex = 0;
//getting index on the basis of braces added to text
if (notificationMessage.contains("(")) {
isPhoneNumberAvailable = true;
phoneStartIndex = notificationMessage.indexOf("(");
phoneEndIndex = notificationMessage.indexOf(")");
}
if (notificationMessage.contains("{")) {
orderIdStartIndex = notificationMessage.indexOf("{");
orderIdEndIndex = notificationMessage.indexOf("}");
}
// we got the index so remove braces
notificationMessage = notificationMessage.replace("(", " ");
notificationMessage = notificationMessage.replace(")", " ");
notificationMessage = notificationMessage.replace("{", " ");
notificationMessage = notificationMessage.replace("}", " ");
viewHolder.txtNotificationMessage.setText(notificationMessage, TextView.BufferType.SPANNABLE);
Spannable mySpannablePhoneNumber = (Spannable) viewHolder.txtNotificationMessage.getText();
Spannable mySpannableOrderID = (Spannable) viewHolder.txtNotificationMessage.getText();
ClickableSpan mySpanPhoneClick = new ClickableSpan() {
@Override
public void onClick(View widget) {
currentPosition = (Integer) widget.getTag();
String message = mArrListNotification.get(currentPosition).getMessage();
int startIndex = message.indexOf("(");
int endIndex = message.indexOf(")");
phoneNumber = message.substring(startIndex + 1, endIndex);
Log.i("Phone Number", phoneNumber clicked)
}
};
ClickableSpan mySpanOrderClick = new ClickableSpan() {
@Override
public void onClick(View widget) {
currentPosition = (Integer) widget.getTag();
String message = mArrListNotification.get(currentPosition).getMessage();
int startIndex = message.indexOf("{");
int endIndex = message.indexOf("}");
String orderID = message.substring(startIndex + 1, endIndex);
// Log.i("Order id", orderID clicked)
}
};
if (isPhoneNumberAvailable) {
mySpannablePhoneNumber.setSpan(mySpanPhoneClick, phoneStartIndex + 1, phoneEndIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
if (isOrderIdAvailable) {
mySpannableOrderID.setSpan(mySpanOrderClick, orderIdStartIndex + 1, orderIdEndIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
I Have Created a generalized function for this purpose hope this helps
fun TextView.makeLinks(vararg links: Triple<String, View.OnClickListener,LinkProperties>) {
try {
val spannableString = SpannableString(this.text)
for (link in links) {
val clickableSpan = object : ClickableSpan() {
override fun updateDrawState(textPaint: TextPaint) {
super.updateDrawState(textPaint)
textPaint.isUnderlineText = link.third.isUnderlineText
textPaint.isFakeBoldText = link.third.isBoldText
textPaint.color = link.third.color ?: Color.parseColor(DCColorPicker.BLACK)
}
override fun onClick(view: View) {
Selection.setSelection((view as TextView).text as Spannable, 0)
view.invalidate()
link.second.onClick(view)
}
}
val startIndexOfLink = this.text.toString().indexOf(link.first)
spannableString.setSpan(
clickableSpan, startIndexOfLink, startIndexOfLink + link.first.length,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
)
}
this.movementMethod = LinkMovementMethod.getInstance() // without LinkMovementMethod, link can not click
this.setText(spannableString, TextView.BufferType.SPANNABLE)
} catch (e: Exception) {
Log.e(TAG, "makeLinks: " + e.message)
}
}
and you can add N no. of properties here
data class LinkProperties(val isUnderlineText: Boolean = false, val isBoldText: Boolean = false, val color: Int?=null)
and for calling you can use this function like this
val linkBoldOnly = LinkProperties(isBoldText = true)
val linkBoldUnderline = LinkProperties(isUnderlineText = true, isBoldText = true)
binding.name.makeLinks(
Triple("text", View.OnClickListener { openMore() }, linkBoldUnderline),
Triple(name.toString(), View.OnClickListener { itemClick() }, linkBoldOnly)
)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.