如何使用单词及其点击事件获取特殊字符
Posted
技术标签:
【中文标题】如何使用单词及其点击事件获取特殊字符【英文标题】:how to get special character with word and its click event 【发布时间】:2018-02-13 12:58:51 【问题描述】:我有一个这样的 3 字符串:
"@Username: Deliverd your order",
"YOU got trophy: KING OF COINS",
"There is a package waiting for you to pick up from #surat to #mumbai",
我想做的是通过点击事件获取不同颜色的用户名和城市名称。
我能够实现的是通过拆分为“:”字符来获取用户名。 但我不知道如何获取城市名称和两者的点击事件。
在城市名称中只有最后一个城市颜色在变化,如何同时更改城市名称颜色并获取其点击事件。
这是我尝试过的:
if (notifications.getTitle().contains(":"))
String[] username = notifications.getTitle().split(":");
String uname = getColoredSpanned(username[0] + ":", "#ff7505");
String txt = getColoredSpanned(username[1], "#000000");
holder.txtTitle.append(html.fromHtml(uname +" " + txt));
holder.txtTitle.setMovementMethod(LinkMovementMethod.getInstance());
else if (notifications.getTitle().contains("#"))
Matcher matcher =
Pattern.compile("#\\s(\\w+)").matcher(notifications.getTitle());
i=0;
while (matcher.find())
place.add(i, matcher.group(1));
i++;
String place1 = getColoredSpanned("#" + place.get(0), "#237BCD");
String place2 = getColoredSpanned("#" + place.get(1), "#237BCD");
places1 = notifications.getTitle().replace("#" + place.get(0), place1);
places1 = notifications.getTitle().replace("#" + place.get(1), place2);
holder.txtTitle.setText(Html.fromHtml(places1));
else
holder.txtTitle.setText(notifications.getTitle());
private String getColoredSpanned(String text, String color)
String input = "<font color=" + color + ">" + text + "</font>";
return input;
这就是我得到的输出:
这是我真正期望的:
【问题讨论】:
***.com/questions/10696986/… 至于如何从文本中获取数据,请尝试以某种更易于解析的方式格式化您的字符串,而不是使用 split(),也许是 json。 我尝试了你的链接,但我可以得到点击事件但无法设置颜色.. 事情是字符串是动态的,所以我不能设置跨度的开始和结束位置。 @vlatkozelka 你的意思是用某种方式格式化你的字符串。这就是我正在做的事情。知道哪种方式比拆分更好。 【参考方案1】:我认为您已经完成了用户名并面临点击城市的问题,所以我已经通过点击城市名称给出了答案。
感谢@Vinay 提供一些提示。
请检查以下代码。
public void setSpan()
String test = "There is a package waiting for you to pick up from #surat to #mumbai";
SpannableString spannable = new SpannableString(test);
final Matcher matcher = Pattern.compile("#\\s*(\\w+)").matcher(test);
while (matcher.find())
final String city = matcher.group(1);
ClickableSpan clickableSpan = new ClickableSpan()
@Override
public void onClick(View textView)
Toast.makeText(mActivity, city, Toast.LENGTH_SHORT).show();
@Override
public void updateDrawState(TextPaint ds)
super.updateDrawState(ds);
ds.setUnderlineText(false);
ds.setColor(Color.RED);
;
int cityIndex = test.indexOf(city) - 1;
spannable.setSpan(clickableSpan, cityIndex, cityIndex + city.length() + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
mTextViewNotification.setText(spannable);
mTextViewNotification.setMovementMethod(LinkMovementMethod.getInstance());
输出截图:
【讨论】:
它只适用于“#”吗?因为我有其他带有“$”符号的文本,并且 doller 符号模式不匹配。 并带有“@”符号,它总是出现类似 java.lang.IndexOutOfBoundsException: setSpan (-2 ... 7) 在 0 之前开始的错误 您必须将此逻辑保留在此 else if (notifications.getTitle().contains("#")) 部分 我知道..我把它保留为“#”值..但我在谈论@和 $ 符号..它在 Pattern.compile 中不起作用,关于“@”符号的任何想法.. 【参考方案2】:为此使用正则表达式。
String str= "There is a package waiting for you to pick up from #surat to #mumbai";
Matcher matcher = Pattern.compile("#\\s*(\\w+)").matcher(str);
while (matcher.find())
System.out.println(matcher.group(1));
输出将是:
surat
mumbai
【讨论】:
但是如何制作最终的字符串..,我应用了您的解决方案,我得到了 surat 和 mumbai 作为输出,我还为这两个地方着色,现在如何添加到 textview 作为最终输出【参考方案3】:要提取带有可点击主题标签的最终描述,请在列表项布局中添加隐藏的LinearLayout
:
<LinearLayout
android:id="@+id/layoutDescription"
android:layout_
android:layout_
android:layout_margin="24dp"
android:orientation="horizontal"
android:visibility="gone" />
修改您的代码以将主题标签与动态TextViews
分开并将它们添加回LinearLayout
:
if (notifications.getTitle().contains(":"))
String[] username = notifications.getTitle().split(":");
String pre_username = getColoredSpanned(username[0] + ":", "#ff7505");
String post_username = getColoredSpanned(username[1], "#000000");
holder.txtTitle.append(Html.fromHtml(pre_username + " " + post_username));
holder.txtTitle.setMovementMethod(LinkMovementMethod.getInstance());
else if (notifications.getTitle().contains("#"))
layoutDescription.setVisibility(View.VISIBLE);
Matcher matcher = Pattern.compile("#\\s(\\w+)").matcher(notifications.getTitle());
List<String> place = new ArrayList<>();
int i = 0;
while (matcher.find())
place.add(i, matcher.group(1));
i++;
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(5, 0, 5, 0); // (left, top, right, bottom)
TextView mHashTagA = new TextView(this);
mHashTagA.setLayoutParams(layoutParams);
mHashTagA.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
Toast.makeText(getApplicationContext(), "Clicked on HashTag A", Toast.LENGTH_SHORT).show();
);
TextView mSeparator = new TextView(this);
mSeparator.setLayoutParams(layoutParams);
mSeparator.setText("to");
TextView mHashTagB = new TextView(this);
mHashTagB.setLayoutParams(layoutParams);
mHashTagB.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
Toast.makeText(getApplicationContext(), "Clicked on HashTag B", Toast.LENGTH_SHORT).show();
);
TextView mDescription = new TextView(getApplicationContext());
mDescription.setTextColor(Color.parseColor("#343434"));
mDescription.setLayoutParams(layoutParams);
String place1 = getColoredSpanned("#" + place.get(0), "#237BCD");
mHashTagA.setText(Html.fromHtml(place1));
String place2 = getColoredSpanned("#" + place.get(1), "#237BCD");
mHashTagB.setText(Html.fromHtml(place2));
String without_hash = notifications.getTitle().split("#")[0];
mDescription.setText(without_hash);
layoutDescription.addView(mDescription);
layoutDescription.addView(mHashTagA);
layoutDescription.addView(mSeparator);
layoutDescription.addView(mHashTagB);
else
layoutDescription.setVisibility(View.GONE);
holder.txtTitle.setText(notifications.getTitle());
最终输出,
【讨论】:
看起来很完美。 看起来很有希望.. 我会尽快尝试.. 那么用户点击事件呢【参考方案4】:试试this library。它是一个井号标签实现,仅适用于 # 。根据您的要求增强此库后,它可能会对您有所帮助。
【讨论】:
不错的图书馆...是的,它可能会有所帮助...谢谢。【参考方案5】:使用 SpannableString,你不需要任何特殊字符,只知道可点击的词索引。如下:
SpannableString styledString
= new SpannableString("There is a package waiting for you to pick up from " +
"surat" + // index 51 - 56
" to " +
"mumbai"); //index 60 - 66
// clickable text for "surat"
ClickableSpan clickableSpan1 = new ClickableSpan()
@Override
public void onClick(View widget)
// We display a Toast. You could do anything you want here.
Toast.makeText(MainActivity.this, "surat clicked", Toast.LENGTH_SHORT).show();
;
// clickable text for "mumbai"
ClickableSpan clickableSpan2 = new ClickableSpan()
@Override
public void onClick(View widget)
// We display a Toast. You could do anything you want here.
Toast.makeText(MainActivity.this, "mumbai clicked", Toast.LENGTH_SHORT).show();
;
styledString.setSpan(clickableSpan1, 51, 56, 0);
styledString.setSpan(clickableSpan2, 60, 66, 0);
textView.setText(styledString);
【讨论】:
以上是关于如何使用单词及其点击事件获取特殊字符的主要内容,如果未能解决你的问题,请参考以下文章