如何获取word中的特殊字符及其点击事件

how to get special character with word and its click event

我有一个像这样的 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;
}

这就是我得到的输出:

这正是我真正期望的:

为此使用正则表达式。

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

要提取带有可点击主题标签的最终描述,请在您的列表项布局中添加一个隐藏的 LinearLayout

<LinearLayout
        android:id="@+id/layoutDescription"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        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());
    }

最终输出,

我想你已经完成了用户名的设置,但在点击城市时遇到了问题,所以我通过点击城市名称给出了答案。

感谢@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());
    }

输出截图:

使用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);

尝试this library。它是一个哈希标签实现,仅适用于#。在根据您的要求增强此库后,它可能会对您有所帮助。