Android 精简版 仿微博 今日头条@人 #话题# 功能

input.png

以上思路是借鉴 https://blog.csdn.net/wbwjx/article/details/66651931
Textview解析借鉴 https://blog.csdn.net/l_lhc/article/details/71105313
可以说是精简版 更加容易看懂实现原理
1.不同的是,删除文字块不需要再次选中才能删除,而是直接删除
先看整体效果图
a1.gif

下面是删除效果
a2.gif

下面是目录
a3.png

下面三个方法开始是没有放在自定义view中,不过最好还是放在里面,方便管理

/**
     * 把选中用户或话题 插入输入框
     * @param insertData
     */
    public void insertText(InsertData insertData) {
        if (insertData == null) return;
        String showText = insertData.showText();
        String uploadFormatText = insertData.uploadFormatText();
        int color = insertData.color();

        Editable editable = getText();
        int start = getSelectionStart();
        int end = start + showText.length();
        // 插入到指定位置
        editable.insert(start, showText);
        // 设置对应颜色
        editable.setSpan(new ForegroundColorSpan(color), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

        // 保存文字块的起始位置+展示字符+发给后端的格式字符
        FormatRangBean range = new FormatRangBean(start, end);
        range.setUploadFormatText(uploadFormatText);
        mRangeManager.add(range);
    }

    /**
     * 每删除一个字符,都要遍历缓存队列,判断是否是删除了队列中的数据
     * 如果删除是文字块前面的文字,对于后面的文字块要往前移位
     * 如果是删除文字块,则把文字块在缓存列表删除后,对于后面的文字块要往前移位
     * @param start
     * @param end
     * @param offset
     */
    public void whenDelText(int start, int end,int offset){
        Iterator iterator = mRangeManager.iterator();
        while (iterator.hasNext()) {
            RangBean rangBean = (RangBean) iterator.next();
            // 判断起始位置是否包裹了文字块,如果包裹了,则把文字块相关信息在内存列表删除
            if (rangBean.isWrapped(start, end)) {
                iterator.remove();
                continue;
            }
            // 将end之后的span,挪动offset个位置
            if (rangBean.getFrom() >= end) {
                rangBean.setOffset(offset);
            }
        }
    }

    /**
     * 获取上传给服务端的格式化数据
     * @return String
     */
    public String getUploadFormatText() {
        String text = getText().toString();
        Collections.sort(mRangeManager);

        int lastRangeTo = 0;
        StringBuilder builder = new StringBuilder("");
        String newChar;
        for (FormatRangBean range : mRangeManager) {
            builder.append(text.substring(lastRangeTo, range.getFrom()));
            // 获取需要上传给后端的数据格式
            newChar = range.getUploadFormatText();
            builder.append(newChar);
            lastRangeTo = range.getTo();
        }
        builder.append(text.substring(lastRangeTo));
        return builder.toString();
    }

其他代码就不贴出来了,具体可参考demo
gitee传送门 https://gitee.com/Pino_W/ait.git

你可能感兴趣的:(Android 精简版 仿微博 今日头条@人 #话题# 功能)