当前位置:   article > 正文

Android 仿小红书话题功能_安卓+仿小红书+发帖界面

安卓+仿小红书+发帖界面

        最近公司开始做社区功能,需要输入#号后,服务器模糊查询话题,查看网上代码,始终跟预想中的有些出入,好久没有写自定义控件了,这里边写边记录,方便给需要使用的人,提供一个记录。难点就是EditText中操作话题的逻辑了

参考链接       

        先看目前暂时实现的效果,已经完成90%的功能了

        

功能如下:

        1.输入#号后,我这里底部隐藏了一个布局(里面展示服务器返回模糊搜索结果),通过删除和输入#来控制隐藏

        2.输入后,话题字体变色

        3.支持多个话题,当移动到话题部分, 自动弹框服务器返回模糊搜索结果

目前论坛上提供的思路,差不多,这里主要是细节分享

        1.android 键盘有中英文#。正则需要修改[\#|#]

        2.有一个功能,是选中全部删除,如果业务需要实时更新模糊输入结果,这里可不需要

        3.滑动到某一个话题时,重新弹框展示服务器返回结果

      

思路代码

一、找到话题

private final String inputReg = "([\\#|#][\u4e00-\u9fa5a-zA-Z]+\\d{0,100})";

  封装一个实体类保存     

  1. public class TopicBean {
  2. private String topicRule = "#";// 匹配规则
  3. private String topicText;// 高亮文本
  4. public int start;
  5. public int end;
  6. }

   如果使用,来匹配满足条件即为一个话题。监听addTextChangedListener事件:

  1. this.addTextChangedListener(new TextWatcher() {
  2. @Override
  3. public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
  4. }
  5. @Override
  6. public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
  7. }
  8. @Override
  9. public void afterTextChanged(Editable editablede) {
  10. Editable editable = getText();
  11. int length = editablede.toString().length();
  12. //赋值话题列表数据
  13. Matcher matcher = pattern.matcher(editable);
  14. mTopicList.clear();
  15. while (matcher.find()) {
  16. TopicBean tObject = new TopicBean();
  17. tObject.setTopicText(editable.toString().substring(matcher.start(), matcher.end()).trim());
  18. tObject.start = matcher.start();
  19. tObject.end = matcher.end();
  20. mTopicList.add(tObject);
  21. }
  22. //记录上一次的长度
  23. preTextLength = length;
  24. //刷新页面
  25. refreshEditTextUI(editable.toString());
  26. }
  27. });

这里的逻辑,其实还比较简单,while循环,找出所有文本中,符合话题#号后的字,存放在List集合中

二、话题变色

        通过刷新方法refreshEditTextUI()我们来改变颜色

        

  1. private void refreshEditTextUI(String content) {
  2. /*
  3. * 重新设置span
  4. */
  5. Editable editable = getText();
  6. int textLength = editable.length();
  7. int findPosition = 0;
  8. if (mTopicList != null && mTopicList.size() > 0) {
  9. for (int i = 0; i < mTopicList.size(); i++) {
  10. final TopicBean object = mTopicList.get(i);
  11. // 文本
  12. String objectText = object.getTopicText();
  13. while (findPosition <= textLength) {
  14. // 获取文本开始下标
  15. findPosition = content.indexOf(objectText, findPosition);
  16. if (findPosition != -1) {
  17. // 设置话题内容前景色高亮
  18. ForegroundColorSpan colorSpan = new ForegroundColorSpan(mForegroundColor);
  19. editable.setSpan(colorSpan, findPosition, findPosition + objectText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
  20. findPosition += objectText.length();
  21. } else {
  22. break;
  23. }
  24. }
  25. }
  26. }
  27. }

这块代码我就直接引用原作者代码片段了,这里ForegroundColorSpan就是改变颜色的

三、如果找到#标识

        EditText中可以选择当前的光标位置,所以我们要重写onSelectionChanged这个方法,这个是当前光标移动的方法

        1.如何知道用户输入了什么

char charAt = getText().toString().charAt(selEnd - 1);

        所以通过以上可以确定2个事件,一个是#开始,一个结束(结束可以已除中文数字外,其余都算结束)

        这里我临时测试写了一份,可以替换成正则实现:

        

  1. if (value.equals("#") || value.equals("#")) {
  2. Log.e("测试代码","onSelectionChanged 检查到光标前一位是 # 或者# 当前位置是" + selEnd);
  3. mStartSymbolPosition = selEnd - 1;
  4. if (mListener != null) {
  5. mListener.onUserInputStart(selEnd);
  6. }
  7. return;
  8. } else if (value.equals(" ") || value.equals("\n")) {
  9. Log.e("测试代码","onSelectionChanged 最后一位状态");
  10. mLastSymbolPosition = selEnd;
  11. if (mListener != null) {
  12. mListener.onUserInputEnd(selEnd);
  13. }
  14. mStartSymbolPosition = 0;
  15. mLastSymbolPosition = 0;
  16. } else if (mStartSymbolPosition >= selEnd) {
  17. Log.e("测试代码","onSelectionChanged 用户做了删除动作并且删除到#号了 ");
  18. if (mListener != null) {
  19. mListener.onUserInputEnd(selEnd);
  20. }
  21. }

  四、支持多个话题监听

            这里还有一个场景,如果一个文章里有3个话题,那么如何做到,滑动到话题,我们就弹出话题模糊搜索呢,这里就需要在光标移动的时候做处理了。判定坐标,在某一个话题位置范围内。代码如下:

  1. if (mTopicList != null) {
  2. for (int i = 0; i < mTopicList.size(); i++) {
  3. Log.e(TAG, "onSelectionChanged = " + mTopicList.get(i));
  4. if (selEnd == mTopicList.get(i).getEnd()) {
  5. //表示用户回到了话题最后的位置,我们又要进入输入模式
  6. if (mListener != null) {
  7. mListener.onUserInputStart(mTopicList.get(i).getStart());
  8. }
  9. mStartSymbolPosition = mTopicList.get(i).getStart();
  10. mLastSymbolPosition = mTopicList.get(i).getEnd();
  11. }
  12. if (selEnd > mTopicList.get(i).getEnd()) {
  13. if (mListener != null) {
  14. mListener.onUserInputEnd(mTopicList.get(i).getEnd());
  15. }
  16. }
  17. }
  18. }

逻辑也比较简单,光标等于其中一个光标时,我就展示弹框,表示用户正在输入。反之隐藏

到这里,就可以完成小红书功能啦~细节部分需要修改。

       

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/750024
推荐阅读
相关标签
  

闽ICP备14008679号