Android:用spannablestring替换string中的匹配项

时间:2014-06-16 12:38:58

标签: android regex replace spannable

我有一个像这样的字符串:"Hello, [user123| Alex]! Visit [club123|my club]"社交网络Vkontakte通过内部链接返回帖子的方式。我想用spannables替换它们,可以点击。

例如我想得到:“你好, Alex !访问我的俱乐部”,其中强调文字是可点击的

我已经找到了方法,如何用字符串替换这样的事件,但无法弄清楚,如何用spannables做到这一点。你能帮我吗? 我的代码:

public String extractLink(String text)
{
    String result=text, text1=text;
    Pattern pattern = Pattern.compile("\\[((id)|(club))[0-9]+\\|\\w+\\]");
    Matcher matcher = pattern.matcher(text);
     List<String> allMatches = new ArrayList<String>();

     while (matcher.find()) {
         //matcher.replaceAll(matcher.group().substring(matcher.group().indexOf("|")+1,matcher.group().indexOf("]")));
       allMatches.add(matcher.group());
       Log.d("MATCH", matcher.group());
     }

    Integer i=0;

        for (i=0; i<allMatches.size();i++)
    {

        text1=result.replaceFirst("\\[((id)|(club))[0-9]+\\|\\w+\\]", allMatches.get(i).substring(allMatches.get(i).indexOf("|")+1,allMatches.get(i).indexOf("]")));
        result=text1;

    }
    return result;
}

1 个答案:

答案 0 :(得分:3)

这可以帮到你:

private List<Hyperlink> listOfLinks = new ArrayList<>();
private Pattern myPattern = Pattern.compile("\\[((id)|(club))[0-9]+\\|\\w+\\]");

public void setTextAndActivateLinks(String text) {

    SpannableString linkableText = new SpannableString(text);

    gatherLinks(linkableText, myPattern);

    for (Hyperlink linkSpec : listOfLinks) {
        linkableText.setSpan(linkSpec.span, linkSpec.start, linkSpec.end, 0);

         SpannableStringBuilder ssb = new SpannableStringBuilder();
         ssb.append(linkableText, 0, linkableText.length());
         ssb.replace(linkSpec.start, linkSpec.end, TODO HERE YOUR REPLACEMENT);
         linkableText = SpannableString.valueOf(ssb);
    }

    setText(linkableText);
}

private void gatherLinks(SpannableString s, Pattern pattern) {
    Matcher m = pattern.matcher(s);

    while (m.find()) {

        int start = m.start();
        int end = m.end();

        Hyperlink link = new Hyperlink();

        link.type = type;
        link.textSpan = s.subSequence(start, end);
        link.color = mLinkColor;
        link.span = new InternalURLSpan(link.textSpan.toString(), link.type, link.color);
        link.start = start;
        link.end = end;

        listOfLinks.add(0, link);
    }

}

public class InternalURLSpan extends ClickableSpan {

    private String clickedSpan;
    private LinkType clickedType;
    private int clickedColor;

    public InternalURLSpan(String span, LinkType type, int color) {
        clickedSpan = span;
        clickedType = type;
        clickedColor = color;
    }

    @Override
    public void updateDrawState(TextPaint ds) {
        ds.bgColor = Color.TRANSPARENT;
        ds.setColor(clickedColor);
        ds.setUnderlineText(false);
    }

    @Override
    public void onClick(View textView) {
        OnClickLinkListener listener = wr_listener.get();
        if (listener != null)
            listener.onClickLink(textView, clickedSpan, clickedType);
    }
}

public static class LocalLinkMovementMethod extends LinkMovementMethod {
    static LocalLinkMovementMethod sInstance;


    public static LocalLinkMovementMethod getInstance() {
        if (sInstance == null)
            sInstance = new LocalLinkMovementMethod();

        return sInstance;
    }

    @Override
    public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
        int action = event.getAction();
        if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) {
            int x = (int) event.getX();
            int y = (int) event.getY();

            x -= widget.getTotalPaddingLeft();
            y -= widget.getTotalPaddingTop();

            x += widget.getScrollX();
            y += widget.getScrollY();

            Layout layout = widget.getLayout();
            int line = layout.getLineForVertical(y);
            int off = layout.getOffsetForHorizontal(line, x);

            ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);

            if (link.length != 0) {
                if (action == MotionEvent.ACTION_UP)
                    link[0].onClick(widget);
                else
                    Selection.setSelection(buffer, buffer.getSpanStart(link[0]), buffer.getSpanEnd(link[0]));

                if (widget instanceof LinkTextView)
                    ((LinkTextView) widget).mHitLink = true;
                return true;
            } else {
                Selection.removeSelection(buffer);
                Touch.onTouchEvent(widget, buffer, event);
                return false;
            }
        }
        return Touch.onTouchEvent(widget, buffer, event);
    }
}

/*
 * Class for storing the information about the Link Location
 */
class Hyperlink {
    LinkType type;
    CharSequence textSpan;
    InternalURLSpan span;
    int start;
    int end;
    int color;
}