Android+文本的查找和替换+可以对文本进行查找替换撤销等,基本实现了PC端.txt查找替换功能

2023-10-29

Android+文本的查找和替换+可以对文本进行查找替换撤销等,基本实现了PC端.txt查找替换功能

最近项目用到了类似PC端记事本查找替换功能,于是自己就写了一套算法,实现起来还是比较容易理解的。基于移动开发的文本查找替换功能,基本实现了PC段记事本查找替换的相关功能。基本功能包括,查找、替换、全部替换、撤销、上一条、下一条、颜色标记和位置定位等功能。

SpannableStringBuilder实现了CharSequence类,用来存储字符串。SpannableStringBuilder有一个setSpan()函数,能给给存储的字符串添加各种各样的格式或者属性,,将原来的String以不同的样式显示出来,比如加上下划线、背景颜色、字体颜色、设置点击监听、设置超链接等。主要用到的就是设置背景颜色。有兴趣的同学可以自行了解一下。
 

查找算法

mBinding.tvSeek.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (TextUtils.isEmpty(mBinding.etName.getText().toString().trim())) {
                    showToast("输入查找内容");
                    return;
                }
                if (!mBinding.tvContent.getText().toString().contains(mBinding.etName.getText().toString())) {
                    showToast("查找内容不存在");
                    listFind = new ArrayList<>();
                    mBinding.tvNumber.setVisibility(View.INVISIBLE);
                    SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(mBinding.tvContent.getText().toString());
                    BackgroundColorSpan colorSpan;
                    colorSpan = new BackgroundColorSpan(Color.parseColor("#ffffff"));
                    spannableStringBuilder.setSpan(colorSpan, 0, mBinding.tvContent.getText().toString().length() - 1, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
                    mBinding.tvContent.setText(spannableStringBuilder);
                    return;
                }
                findKey = mBinding.etName.getText().toString();
                listReplace = new ArrayList<>();
                mBinding.tvContent.getText().toString().contains(mBinding.etName.getText().toString());
                getSubString(mBinding.tvContent.getText().toString(), findKey);
                SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(mBinding.tvContent.getText().toString());
                if (listFind != null && listFind.size() != 0) {
                    for (int i = 0; i < listFind.size(); i++) {
                        BackgroundColorSpan colorSpan;
                        if (i == 0) {
                            colorSpan = new BackgroundColorSpan(Color.parseColor("#f50707"));
                        } else {
                            colorSpan = new BackgroundColorSpan(Color.parseColor("#AC00FF30"));
                        }
                        spannableStringBuilder.setSpan(colorSpan, listFind.get(i).getStart(), listFind.get(i).getEnd(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
                    }
                    mBinding.tvNumber.setVisibility(View.VISIBLE);
                    mBinding.tvNumber.setText("查找到" + listFind.size() + "条内容");
                } else {
                    BackgroundColorSpan colorSpan;
                    colorSpan = new BackgroundColorSpan(Color.parseColor("#212832"));
                    spannableStringBuilder.setSpan(colorSpan, 0, mBinding.tvContent.getText().length() - 1, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
                    mBinding.tvNumber.setVisibility(View.INVISIBLE);
                }
                mBinding.tvContent.setText(spannableStringBuilder);

            }
        });

查找定位算法

mBinding.tvPrevious.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (listFind != null && listFind.size() != 0) {
                    if (select > 0) {
                        select = select - 1;
                    } else if (select == 0) {
                        select = listFind.size() - 1;
                    }
                } else {
                    return;
                }
                next();
            }
        });

private void next() {
        SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(mBinding.tvContent.getText().toString());
        if (listFind != null && listFind.size() != 0) {
            for (int i = 0; i < listFind.size(); i++) {
                BackgroundColorSpan colorSpan = new BackgroundColorSpan(Color.parseColor("#AC00FF30"));
                spannableStringBuilder.setSpan(colorSpan, listFind.get(i).getStart(), listFind.get(i).getEnd(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
            }
        }
        if (listReplace != null && listReplace.size() != 0) {
            for (int i = 0; i < listReplace.size(); i++) {
                BackgroundColorSpan colorSpan = new BackgroundColorSpan(Color.parseColor("#f5e107"));
                spannableStringBuilder.setSpan(colorSpan, listReplace.get(i).getStart(), listReplace.get(i).getEnd(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
            }
        }
        BackgroundColorSpan colorSpan = new BackgroundColorSpan(Color.parseColor("#f50707"));
        spannableStringBuilder.setSpan(colorSpan, listFind.get(select).getStart(), listFind.get(select).getEnd(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);

        mBinding.tvContent.setText(spannableStringBuilder);
        mBinding.tvContent.setSelection(listFind.get(select).getStart(), listFind.get(select).getEnd());

    }

替换算法

  mBinding.tvReplace.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (TextUtils.isEmpty(findKey)) {
                    showToast("输入查找内容");
                    return;
                }
                if (TextUtils.isEmpty(mBinding.etNames.getText().toString())) {
                    showToast("输入替换内容");
                    return;
                }
                replaceKey = mBinding.etNames.getText().toString();
                if (listFind != null && listFind.size() != 0) {
                    if (select <= listFind.size() - 1) {

                    } else {
                        select = 0;
                    }
                } else {
                    showToast("没找到要替换的内容");
                    return;
                }

                if (select < listFind.size()) {
                } else {
                    showToast("没找到要替换的内容");
                    return;
                }
                SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(mBinding.tvContent.getText().toString());
                spannableStringBuilder.replace(listFind.get(select).getStart(), listFind.get(select).getEnd(), replaceKey);

                FindBean findBean = new FindBean();
                findBean.setStart(listFind.get(select).getStart());
                findBean.setEnd(listFind.get(select).getStart() + replaceKey.length());
                listReplace.add(findBean);
                listFind.remove(select);
                if (listFind != null && listFind.size() != 0) {
                    for (int i = 0; i < listFind.size(); i++) {
                        if (listFind.get(i).getStart() > findBean.getStart()) {
                            int sub1 = findBean.getEnd() - findBean.getStart();
                            int sub2 = listFind.get(i).getEnd() - listFind.get(i).getStart();
                            listFind.get(i).setStart(listFind.get(i).getStart() + sub1 - sub2);
                            listFind.get(i).setEnd(listFind.get(i).getEnd() + sub1 - sub2);
                        }
                    }
                }
                if (listReplace != null && listReplace.size() != 0) {
                    for (int i = 0; i < listReplace.size(); i++) {
                        if (listReplace.get(i).getStart() > findBean.getStart()) {
                            int sub1 = findBean.getEnd() - findBean.getStart();
                            listReplace.get(i).setStart(listReplace.get(i).getStart() + sub1 - findKey.length());
                            listReplace.get(i).setEnd(listReplace.get(i).getEnd() + sub1 - findKey.length());
                        }
                    }
                }


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

                    BackgroundColorSpan colorSpan;
                    if (i == select) {
                        colorSpan = new BackgroundColorSpan(Color.parseColor("#f50707"));
                    } else {
                        colorSpan = new BackgroundColorSpan(Color.parseColor("#AC00FF30"));
                    }

                    spannableStringBuilder.setSpan(colorSpan, listFind.get(i).getStart(), listFind.get(i).getEnd(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);


                }
                for (int i = 0; i < listReplace.size(); i++) {
                    BackgroundColorSpan colorSpan = new BackgroundColorSpan(Color.parseColor("#f5e107"));
                    spannableStringBuilder.setSpan(colorSpan, listReplace.get(i).getStart(), listReplace.get(i).getEnd(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
                }
                mBinding.tvContent.setText(spannableStringBuilder);
                mBinding.tvContent.setSelection(listFind.get(select).getStart(), listFind.get(select).getEnd());

            }
        });

撤销算法

mBinding.tvUndo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (listReplace != null && listReplace.size() != 0) {
                    SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(mBinding.tvContent.getText().toString());
                    spannableStringBuilder.replace(listReplace.get(listReplace.size() - 1).getStart(), listReplace.get(listReplace.size() - 1).getEnd(), findKey);
                    FindBean findBean = new FindBean();
                    findBean.setStart(listReplace.get(listReplace.size() - 1).getStart());
                    findBean.setEnd(listReplace.get(listReplace.size() - 1).getStart() + findKey.length());
                    listFind.add(findBean);
                    Collections.sort(listFind, new Comparator<FindBean>() {
                        @Override
                        public int compare(FindBean o1, FindBean o2) {
                            int diff = o1.getStart() - o2.getStart();
                            if (diff > 0) {
                                return 1;
                            } else if (diff < 0) {
                                return -1;
                            }
                            return 0; //相等为0
                        }
                    });
                    select = listFind.indexOf(findBean);
                    listReplace.remove(listReplace.size() - 1);
                    if (listFind != null && listFind.size() != 0) {
                        for (int i = 0; i < listFind.size(); i++) {
                            if (listFind.get(i).getStart() > findBean.getStart()) {
                                int sub1 = findBean.getEnd() - findBean.getStart();
                                listFind.get(i).setStart(listFind.get(i).getStart() + sub1 - replaceKey.length());
                                listFind.get(i).setEnd(listFind.get(i).getEnd() + sub1 - replaceKey.length());
                            }
                        }
                    }
                    if (listReplace != null && listReplace.size() != 0) {
                        for (int i = 0; i < listReplace.size(); i++) {
                            if (listReplace.get(i).getStart() > findBean.getStart()) {
                                int sub1 = findBean.getEnd() - findBean.getStart();
                                int sub2 = listReplace.get(i).getEnd() - listReplace.get(i).getStart();
                                listReplace.get(i).setStart(listReplace.get(i).getStart() + sub1 - sub2);
                                listReplace.get(i).setEnd(listReplace.get(i).getEnd() + sub1 - sub2);
                            }
                        }
                    }


                    for (int i = 0; i < listFind.size(); i++) {
                        BackgroundColorSpan colorSpan = new BackgroundColorSpan(Color.parseColor("#AC00FF30"));
                        spannableStringBuilder.setSpan(colorSpan, listFind.get(i).getStart(), listFind.get(i).getEnd(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
                    }
                    for (int i = 0; i < listReplace.size(); i++) {
                        BackgroundColorSpan colorSpan = new BackgroundColorSpan(Color.parseColor("#f5e107"));
                        spannableStringBuilder.setSpan(colorSpan, listReplace.get(i).getStart(), listReplace.get(i).getEnd(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
                    }
                    mBinding.tvContent.setText(spannableStringBuilder);
                    mBinding.tvContent.setSelection(listFind.get(select).getStart(), listFind.get(select).getEnd());
                } else {
                    showToast("撤销完毕");
                }
            }
        });

记录下标位置对象

public class FindBean {
    private int start;
    private int end;

    public int getStart() {
        return start;
    }

    public void setStart(int start) {
        this.start = start;
    }

    public int getEnd() {
        return end;
    }

    public void setEnd(int end) {
        this.end = end;
    }
}

了解具体做法可以产看demo:Android+文本的查找和替换+可以对文本进行查找替换撤销等,基本实现了PC端.txt查找替换功能-Android文档类资源-CSDN文库

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android+文本的查找和替换+可以对文本进行查找替换撤销等,基本实现了PC端.txt查找替换功能 的相关文章

  • Android Studio如何添加工程(project)为library(针对非gradle)

    这篇文章还是针对非gradle build的工程 gradle build有一些差别 在Eclipse要引用别的工程为本工程的library很简单 但是在Android Studio还是稍稍有点小复杂的 那如何引用别的工程为本工程的libr
  • 阿里云P2P内容分发网络(PCDN)实操手册

    一 PCDN是定义 P2P 内容分发网络 英文名 P2P CDN 以下简称PCDN 是以P2P技术为基础 通过挖掘利用电信边缘网络海量碎片化闲置资源而构建的低成本高品质内容分发网络服务 客户通过集成PCDN SDK 以下简称SDK 接入该服
  • 从微信授权登录到数据安全性的思考总结

    前置知识 微信授权登录过程和相关名词 access token code openid等 微信授权登录 大都是拉起微信授权页面 用户同意授权后 再跳到自己应用的绑定手机页面进行绑定手机的操作 绑定之后自动登录 会话就像不会过期一样 或者是过
  • 金三银四必备,全面总结 Kotlin 面试知识点

    作者 彭旭锐 前言 在 Android 面试中很重视基础知识的考察 其中语言基础主要包括 Java Kotlin C C 三种编程语言 在小彭面试的经验中 发现很多同学的 Kotlin 语言能力只是停留在一些非常入门的语法使用上 在这篇文章
  • 基于linux的调试技术

    虽然使用printk函数可以很方便的将消息写入日志文件或者控制台 但是大量使用printk函数频繁的操作日志文件或者控制台文件会严重影响到linux驱动的开发性能 因此 这就需要linux驱动在开发阶段使用printk函数输出消息 在正式发
  • IBM Worklight开发环境安装

    1 安装jdk1 6以上版本 2 下载安装mysql http ftp iij ad jp pub db mysql Downloads MySQL 5 1 mysql noinstall 5 1 62 win32 zip 3 下载mysq
  • 用BeanUtils类自动封装表单数据

    导入架包 commons beautils 1 8 0 jar commons logging jar Class
  • 买《Kotlin从小白到大牛》专题视频课程,送配套纸质图书

    经过一年多时间的呕心沥血 Kotlin立体化图书 Kotlin从小白到大牛 即将与大家见面了 所谓立体化图书包括 电子图书 视频 课件和服务等内容 Kotlin从小白到大牛 纸质图书已经上市 为了答谢广大学员对智捷课堂以及关老师的支持 现购
  • Android智能下拉刷新框架-SmartRefreshLayout

    框架 下拉刷新控件还能框架化 智能又怎么回事 二话不多少先上Demo效果图 咱们再来探个究竟 Github 传送门注意 本文仅仅是博客文章 主要用于项目介绍和宣传 由于发布时间关系 部分内容已经过期 详细使用文档请跳转 github Dem
  • mongodb如何实现数组对象求和

    原本地址 mongodb如何实现数组对象求和 mongodb在计算集合数组值时候 我们通常会想到使用 group与 sum 但是如果是数组里面多个json对象 并且还需要根据条件过滤多个对象的内容该如何处理 现在让我们来实现它 假设mong
  • arcgis for android 学习 - (5) 在地图指定位置添加“标记“,并尝试选中它

    我做一个例子 1 首先显示一个地图 2 点击 添加要素 按钮后再次点击地图 将会在地图上添加 红色的位置标记 3 再次点击按钮后 这时 就可以点击刚刚添加的 红色的位置标记 就可以查看到 该标记关联到得属性值 布局
  • Lottie动画概述,文末有彩蛋

    原生的动画效果有时候写起来会非常的复杂 要考虑到很多兼容和效果 Lottie动画专门为了解决这种烦恼而产生的 注 不仅是Lottie可以做到 另外一种库也可以做到将动画分成一帧一帧展示 它就是 android gif drawable 库
  • 深入理解 Flutter 图片加载原理

    前言 随着Flutter稳定版本逐步迭代更新 京东APP内部的Flutter业务也日益增多 Flutter开发为我们提供了高效的开发环境 优秀的跨平台适配 丰富的功能组件及动画 接近原生的交互体验 但随之也带来了一些OOM问题 通过线上监控
  • Android RecyclerView最全使用详解

    本文目录 RecyclerView概述 RecyclerView使用 基础篇 第一步 添加RecyclerView 第二步 添加布局文件 第三步 添加逻辑代码 运行效果 RecyclerView使用 进阶篇 布局管理器 线性布局管理器 网格
  • 阿里P7大牛亲自教你!妈妈再也不用担心我的面试,讲的明明白白!

    第一次观看我文章的朋友 可以关注 点赞 转发一下 每天分享各种干货技术和程序猿趣事 前言 随着移动终端的快速发展 Android开发人员也越来越多 Android开发市场也进入了一个饱和的状态 Android开发人员也面临着难找一份好工作的
  • 史上最全的《Android面试题及解析》,赶紧收藏!

    写在文章前面的话 工欲行其事 必先利其器 英雄和侠客更需要宝剑助己成功 同样 在现代软件开发环境中 每个Android开发者都需要更好的工具 帮助我们增强功能 提高效率 在这个竞争激烈的行业中 只有优秀的工程师能够生存 需要我们能够为客户提
  • 虹软人脸识别 - ArcFace SDK介绍及使用注意事项

    很多朋友在开发人脸识别系统的时候 会遇到各种各样的问题 现在我们以安卓平台使用虹软的免费离线人脸识别SDK开发为例 给大家介绍一下如何开发一个带有图片的人脸检测 视频画面的人脸属性检测 人脸注册识别等功能的人脸识别系统 一 获取SDK 1
  • android Scroller

    参考 http www linuxidc com Linux 2016 01 127276 htm 以前只知道怎么使用scroller 照猫画虎 复制粘贴 今天遇到使用scroller 还是要去搜索 这样不行 要搞懂原理 上面的博客写的很漂
  • ​第一本 Compose 图书上市,联想大咖教你学会 Android 全新 UI 编程

    朱江 现任联想 北京 有限公司 Android 开发工程师 从事 Android 开发工作多年 有丰富的项目经验 负责和参与开发过多款移动应用程序 同时还是多个开源项目的作者 2017 年开始在 CSDN 发表 Android 技术相关博文
  • Android Framework——进程间通讯学习,从Binder使用看起

    前言 Binder 是安卓中非常重要的进程间通讯工具 通过Binder 安卓在ServiceManager中对外提供了一系列的服务 学习Binder 将很好地为我们学习framework开个好头 Android 使用多进程 Android

随机推荐

  • PCL 欧式聚类分割

    目录 一 算法原理 1 实现流程 2 实现方法 3 核心代码 4 参考文献 二 代码实现 三 结果展示 四 应用案例 五 保存结果 六 不调库实现 一 算法原理 1 实现流程 欧式聚类是一种基于欧氏距离度量的聚类算法 基于KD Tree的近
  • Docker 入门到实战教程(一)介绍Docker

    一 Docker简介 1 1 什么是虚拟化 在计算机中 虚拟化 英语 Virtualization 是一种资源管理技术 是将计算机的各种实体资源 如服务器 网络 内存及存储等 予以抽象 转换后呈现出来 打破实体结构间的不可切割的障碍 使用户
  • hadoop web查看集群datanode 信息不全

    环境说明 同一主机上 两台ubuntu虚拟机 问题 启动Hadoop后 两个节点上的jps查看进程正常 可web登录50070端口 查看的datanode information 只显示的本机上的datanode信息 namenode上jp
  • Serializable序列化实例

    需要序列化的对象 package com zizhu import java io Serializable public class SerializableHello implements Serializable private st
  • 工具类——Java导出EXCEL2(设置样式、加载并填充图片、加载指定模板、大数据量设置窗口大小与刷新频率)

    文章目录 一 POI设置样式 二 POI导出图片 1 解释XSSFClientAnchor 三 加载指定模板导出 四 Workbook XSSFWorkbook与SXSSFWorkbook 1 大数据量导出 1 根据数据量选择XSSFWor
  • ora-12801错误

    今天开发人员遇到如下错误 SQL gt SELECT from 2 FT SB FCS C 3 FT DJ FCDJ D 4 WHERE C YXBZ Y 5 AND C CQZH D FCDJXH 6 AND D ZYBZ Y 7 AND
  • Stress-ng

    介绍如何在 Linux 系统上使用 stress ng 负载测试工具 产生 CPU 内存等资源满载的状况 stress ng stress ng 与旧的 stress 都可以用来产生系统负载 但新的 stress ng 功能较丰富 所以这里
  • C++入门(2/2)

    目录 一 内联函数 二 auto关键字 C 11 三 范围for 四 nullptr 一 内联函数 C 用inline修饰的函数 会在编译时在调用内联函数的地方展开 没有了函数调用建立栈帧的开销 内联函数提升程序运行的效率 对于一个短小的函
  • ubuntu解决连不上网问题(无网关篇)

    今天用ubuntu时发现系统连不上网了 可能是之前捣鼓虚拟机作为ftp服务器导致的 windows下ipconfig命令查看到虚拟机的默认网关是空的 知道了是ubuntu默认网关没配好的原因 参考了这篇博客 如下 1条消息 虚拟机ping不
  • 1 两数之和

    题目描述 给定一个整数数组 nums 和一个目标值 target 请你在该数组中找出和为目标值的那 两个 整数 并返回他们的数组下标 你可以假设每种输入只会对应一个答案 但是 数组中同一个元素不能使用两遍 示例 给定 nums 2 7 11
  • 2-27-Exploring Cross-Image Pixel Contrast for Semantic Segmentation(arxiv2021)有代码

    原文链接 http www myzaker com article 60348715b15ec0509c7170d3 在这篇论文中 研究者提出了一种新的 全监督语义分割训练范式 像素对比学习 强调利用训练集中 跨图像的像素 像素对应关系来学
  • 找最长公共子串

    题目 小明有两个字符串 可能包含空格 小明想找出其中最长的公共连续子串 希望你能帮助他 并输出其长度 输入描述 输入为两行字符串 可能包含空格 长度均小于等于50 输出描述 输出为一个整数 表示最长公共连续子串的长度 示例1 输入 abcd
  • vue使用vue-pdf

    效果 引入vue pdf npm install save vue pdf vue版本 vue 2 6 11 vue pdf 4 3 0 1 在使用页面引入 import pdf from vue pdf components 组件 sea
  • 【概念】为什么区块链被称为分布式数据库?举例讲解分布式数据库包会教程。区块链分布式数据库到底是什么?什么是分布式数据库?一千六百字讲清楚什么事分布式数据库。

    目录 前言 区块链是什么 为什么说是分布式数据库 去中心化 分布式网络 分布式数据库 前言 随着区块链慢慢走进大众视野 大家也能发现 网上许多教程都说区块链是分布式数据库 区块链技术是基于比特币应用提出的一个概念 他是一个融合了多种技术的一
  • FairMOT yolov5s转onnx

    代码 https github com ifzhang FairMOT 论文讲解参考 https blog csdn net weixin 42398658 article details 110873083 https www 163 c
  • Gradle 系列第二讲-android studio中的四个Gradle相关文件讲解

    在android studio中 我们创建一个android项目 会自动生成以下6个gradle的相关文件或文件夹 下面我们来依次全面解析这几个文件的内容和具体的作用 android project gradlew gradlew bat
  • 创建一个子窗口,MouseMove消息一直在触发的解决方法

    条件 在主窗口中 创建 create 一个Child属性的子窗口 在子窗口中使用MouseMove消息时 发现 该消息一直被触发 在domal一个Child属性的子窗口时却没有这个问题 为什么呢 原因在CWnd Create中WS POPU
  • DDL数据库及表的创建删除与使用

    Mysql gt DDL 一 DDL操作数据库 1 1查询 1 2创建数据库 1 3删除数据库 1 4使用数据库 二 DDL操作表 2 1查询表 2 2创建表 2 3数据类型 2 4删除表 2 5修改表 三 总结 一 DDL操作数据库 1
  • 隐私计算项目评估的“偏见”

    如何评估一个项目是不是值得投资 这件事情可能VC最有专业性 本文站在一线工作者的角度 阐述目前隐私计算项目的深浅 有些东西 一定是老百姓口中说出来的可能更贴近现实 做硬件的拼技术 荷兰ASML公司是全球最大的光刻机制造商 也是全球唯一可以提
  • Android+文本的查找和替换+可以对文本进行查找替换撤销等,基本实现了PC端.txt查找替换功能

    Android 文本的查找和替换 可以对文本进行查找替换撤销等 基本实现了PC端 txt查找替换功能 最近项目用到了类似PC端记事本查找替换功能 于是自己就写了一套算法 实现起来还是比较容易理解的 基于移动开发的文本查找替换功能 基本实现了