Android中使用TextView实现微博@功能

前言

在Android中使用TextView实现@功能主要需要用到以下两个知识点:

实现思路

  1. 使用正则表达式找出字符串中所有 @用户名 部分在字符串中的起止位置;
  2. 初始化一个 SpannableString ,利用第一步中获取的起止位置来设置 ClickableSpan;
  3. 将 SpannableString 设置给 TextView

具体实现

一、使用正则表达式找出字符串中所有 @用户名 的部分

1.1 根据 @用户名 的命名匹配规则,编写正则表达式

如匹配规则为:

  • 以@开头
  • 用户名可为字母、下划线、中文,长度为4-30个字符
  • 空格结尾

则正则表达式可定义为:

String NAME_RULE = "@[a-zA-Z_\u4e00-\u9fa5]{4,30} ";

PS:正则表达式必须根据需求给定的命名规则来定

1.2 找出字符串中所有符合正则匹配的部分,并记录其信息(开始的位置、结束的位置、文字内容)

首先我们先定义一个模型类 AtBean 来存放匹配部分的信息

AtBean.class

public class AtBean {
    //文字
    private String name;
    //开始的位置
    private int startPos;
    //结束的位置
    private int endPos;

    public AtBean(String name, int startPos, int endPos) {
        this.name = name;
        this.startPos = startPos;
        this.endPos = endPos;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getStartPos() {
        return startPos;
    }

    public void setStartPos(int startPos) {
        this.startPos = startPos;
    }

    public int getEndPos() {
        return endPos;
    }

    public void setEndPos(int endPos) {
        this.endPos = endPos;
    }

    @Override
    public String toString() {
        return "name --> " + name + "  startPos --> " + startPos + "  endPos --> " + endPos;
    }
}

进行正则匹配,将获取到的信息保存到数组 atBeanList 中

getAtBeanList(String str)

private List<AtBean> getAtBeanList(String str) {

    List<AtBean> atBeanList = new ArrayList<>();

    // 正则表达式
    String NAME_RULE = "@[a-zA-Z_\u4e00-\u9fa5]{4,30} ";

    // 编译正则表达式
    Pattern pattern = Pattern.compile(NAME_RULE);

    Matcher m = pattern.matcher(str);

    while (m.find()) {
        AtBean bean = new AtBean(m.group(), m.start(), m.end());
        atBeanList.add(bean);
        Log.i("Find AT String", bean.toString());
    }
    return atBeanList;
}

二、设置 SpannableString

2.1 新建 ClickableSpan 的子类 Clickable ,为 @用户名 设置样式和点击事件

Clickable.class

private class Clickable extends ClickableSpan implements View.OnClickListener {
    private View.OnClickListener mListener;
    private Context context;

    private Clickable(Context context,View.OnClickListener mListener) {
        this.context = context;
        this.mListener = mListener;
    }

    //设置显示样式
    @Override
    public void updateDrawState(TextPaint ds) {
        super.updateDrawState(ds);
        ds.setColor(ContextCompat.getColor(context, R.color.colorPrimary));//设置颜色
        ds.setUnderlineText(false);//设置下划线
    }

    @Override
    public void onClick(View v) {
        mListener.onClick(v);
    }
}

2.2 将 Clickable 添加到 SpannableString 中

getClickSpannableString(String str, List atBeanList)

private SpannableString getClickSpannableString(String str, List<AtBean> atBeanList) {
    SpannableString spannableStr = new SpannableString(str);
    for (final AtBean atBean : atBeanList) {
        spannableStr.setSpan(new Clickable(MainActivity.this,new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //每个 @用户名 字符串的点击事件
                Toast.makeText(MainActivity.this, "点击了 ————> " + atBean.getName(), Toast.LENGTH_SHORT).show();
            }
        }), atBean.getStartPos(), atBean.getEndPos(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    }
    return spannableStr;
}

三、将 SpannableString 设置给 TextView

    List<AtBean> atBeanList = getAtBeanList(str);
    SpannableString spannableStr = getClickSpannableString(str, atBeanList);
    showTv.setText(spannableStr);
    //激活点击事件
    showTv.setMovementMethod(LinkMovementMethod.getInstance());

完整代码地址:https://github.com/HC-lee/AtTextView

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值