Android ——仿微博添加标签话题的EditText

在github上找到的一个仿微博控件,自己加以完善,实现了用户输入的时候自动识别是否输入了标签

public class TagEditTextView extends AppCompatEditText   {
    private int preTextLength = 0;
    // 默认,话题文本高亮颜色
    private static final int FOREGROUND_COLOR = Color.parseColor("#ffa500");
    // 默认,话题背景高亮颜色
    private static final int BACKGROUND_COLOR = Color.parseColor("#C8C8C8");
    private TextWatcher textWatcher = new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            for (Topic t : tag_list) {
                if (s.toString().contains(String.format("#%s#", t.name)) && t.can_publish == 1) {
                    setObject(t, true);
                }
            }
        }

        @Override
        public void afterTextChanged(Editable s) {
            Editable editable = getText();
            int length = s.toString().length();

            //删除
            if (length < preTextLength) {
                int selectionStart = getSelectionStart();
                int selectionEnd = getSelectionEnd();


                /*
                 * 如果光标起始和结束不在同一位置,删除文本
                 */
                if (selectionStart != selectionEnd) {
                    // 查询文本是否属于话题对象,若是移除列表数据
                    String tagetText = getText().toString().substring(selectionStart, selectionEnd);
                    for (int i = 0; i < mTObjectsList.size(); i++) {
                        Topic object = mTObjectsList.get(i);
                        if (tagetText.equals(object.name)) {
                            mTObjectsList.remove(object);
                        }
                    }
                    return;
                }

                int lastPos = 0;
                if (mTObjectsList != null && mTObjectsList.size() > 0) {
                    // 遍历判断光标的位置
                    for (int i = 0; i < mTObjectsList.size(); i++) {

                        String objectText = mTObjectsList.get(i).name;

                        lastPos = getText().toString().indexOf(objectText, lastPos);
                        if (lastPos != -1) {
                            if (selectionStart != 0 && selectionStart >= lastPos && selectionStart <= (lastPos + objectText.length())) {
                                // 选中话题
                                setSelection(lastPos, lastPos + objectText.length());
                                // 设置背景色
                                editable.setSpan(new BackgroundColorSpan(
                                                mBackgroundColor), lastPos, lastPos
                                                + objectText.length(),
                                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                                return;
                            }
                            lastPos += objectText.length();
                        }
                    }
                }

            }
            preTextLength = length;
            refreshEditTextUI(editable.toString());
        }
    };

    // 话题文本高亮颜色
    private int mForegroundColor = FOREGROUND_COLOR;

    // 话题背景高亮颜色
    private int mBackgroundColor = BACKGROUND_COLOR;

    private List mTObjectsList = new ArrayList<>();// object集合
    private List tag_list = new ArrayList<>();

    public TagEditTextView(Context context) {
        super(context);
        init();
    }

    public TagEditTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TagEditTextView);
        mBackgroundColor = typedArray.getColor(R.styleable.TagEditTextView_tag_background, BACKGROUND_COLOR);
        mForegroundColor = typedArray.getColor(R.styleable.TagEditTextView_tag_color, FOREGROUND_COLOR);
        typedArray.recycle();
        init();
    }

    public TagEditTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TagEditTextView);
        mBackgroundColor = typedArray.getColor(R.styleable.TagEditTextView_tag_background, BACKGROUND_COLOR);
        mForegroundColor = typedArray.getColor(R.styleable.TagEditTextView_tag_color, FOREGROUND_COLOR);
        typedArray.recycle();
        init();
    }


    /**
     * 监听光标的位置,若光标处于话题内容中间则移动光标到话题结束位置
     */
    @Override
    protected void onSelectionChanged(int selStart, int selEnd) {
        super.onSelectionChanged(selStart, selEnd);

        if (mTObjectsList == null || mTObjectsList.size() == 0) {
            return;
        }

        int startPosition = 0;
        int endPosition = 0;
        String objectText = "";

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

            objectText = mTObjectsList.get(i).name;
            int length = getText().toString().length();

            while (true) {
                // 获取话题文本开始下标
                startPosition = getText().toString().indexOf(objectText, startPosition);
                endPosition = startPosition + objectText.length();
                if (startPosition == -1) {
                    break;
                }
                // 若光标处于话题内容中间则移动光标到话题结束位置
                if (selStart > startPosition && selStart <= endPosition) {
                    if ((endPosition + 1) > length) {
                        setSelection(endPosition);
                    } else {
                        setSelection(endPosition + 1);
                    }
                    break;
                }
                startPosition = endPosition;
            }


        }

    }

    public void setAutoAddTag(List tag_list) {
        this.tag_list = tag_list;
    }

    private void init() {

        this.addTextChangedListener(textWatcher);

    }


    private void refreshEditTextUI(String content) {

        /*
         * 内容变化时操作:
         * 1.查找匹配所有话题内容
         * 2.设置话题内容特殊颜色
         */
        if (mTObjectsList.size() == 0)
            return;

        if (TextUtils.isEmpty(content)) {
            mTObjectsList.clear();
            return;
        }

        /*
         * 重新设置span
         */
        Editable editable = getText();
        int textLength = editable.length();

        int findPosition = 0;
        for (int i = 0; i < mTObjectsList.size(); i++) {
            final Topic object = mTObjectsList.get(i);
            // 文本
            String objectText = object.name;
            while (findPosition <= length()) {
                // 获取文本开始下标
                findPosition = content.indexOf(objectText, findPosition);
                if (findPosition != -1) {
                    // 设置话题内容前景色高亮
                    ForegroundColorSpan colorSpan = new ForegroundColorSpan(mForegroundColor);
                    editable.setSpan(colorSpan, findPosition, findPosition + objectText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                    findPosition += objectText.length();
                } else {
                    break;
                }
            }

        }

    }


    /**
     * 插入/设置话题
     *
     * @param object 话题对象
     */
    public void setObject(Topic object, boolean isAuto) {
        if (isAuto) {
            removeTextChangedListener(textWatcher);
        }
        String objectRule = "#";

        if (object == null) {
            return;
        }
        if (object.name.startsWith("#") && object.name.endsWith("#")) {
            objectRule = "";
        }
        String objectText = object.name;
        if (TextUtils.isEmpty(objectText)) {
            return;
        }

        // 拼接字符# %s #,并保存
        objectText = objectRule + objectText + objectRule;
        object.name = objectText.trim();

        /*
         * 1.添加话题内容到数据集合
         */
        mTObjectsList.add(object);

        /*
         * 2.将话题内容添加到EditText中展示
         */
        // 光标位置
        int selectionStart = getSelectionStart();
        // 原先内容
        Editable editable = getText();

        if (selectionStart >= 0) {
            // 在光标位置插入内容  话题后面插入空格,至关重要
            editable.insert(selectionStart, objectText + " ");
//            editable.insert(getSelectionStart(), " ");

            setSelection(getSelectionStart());// 移动光标到添加的内容后面
        }
        if (isAuto) {
            init();
        }
    }

    /**
     * 获取object列表数据
     */
    public List getObjects() {
        List objectsList = new ArrayList();
        // 由于保存时候文本内容添加了匹配字符#,此处去除,还原数据
        if (mTObjectsList != null && mTObjectsList.size() > 0) {
            for (int i = 0; i < mTObjectsList.size(); i++) {
                Topic object = mTObjectsList.get(i);
                String objectText = object.name;
                String objectRule = "#";
                object.name = objectText.replace(objectRule, "");// 将匹配规则字符替换
                objectsList.add(object);
            }
        }
        return objectsList;
    }


}

 

你可能感兴趣的:(新手爬坑系列)