富文本编辑器框架(富文本编辑器的作用)

富文本编辑器框架(富文本编辑器的作用)p id 0FLMLMQ8 点击上方蓝字关注我 知识会给你力量 p p id 0FLMLMQE Span 是 Android 文本系统中一个非常重要的功能 对于它的一般使用 其实比较简单 但在处理一些复杂业务时 Span 的边界问题处理就显得非常重要了 不然很容易因为边界情况没有处理好 导致一系列很麻烦的 bug p

大家好,我是讯享网,很高兴认识大家。




讯享网

 <p id="0FLMLMQ8">点击上方蓝字关注我,知识会给你力量</p><p id="0FLMLMQE">Span是Android文本系统中一个非常重要的功能,对于它的一般使用,其实比较简单,但在处理一些复杂业务时,Span的边界问题处理就显得非常重要了,不然很容易因为边界情况没有处理好,导致一系列很麻烦的bug。</p><p>setSpan</p><p id="0FLMLMQF">注意这里的range,start…end,end是text.length,正好将所有文字Span化,如果start…end超过0…text.length的区间,那么就会产生IndexOutOfBoundsException,由此可知,setSpan中的range,是一个左闭右开区间。</p><p id="0FLMLMQG">[ start … end ) —— [ 0 … length )</p><p>getSpans</p><p id="0FLMLMQH">与setSpan类似,我们通过getSpans来找到range里面的所有指定类型span,那么这里的start…end呢,我们先试下0…length,0…length - 1,0…length + 1,-1…length,-1…length + 1,length - 1…length + 1,-1…1这几种情况。</p><p id="0FLMLMQI">不出意外,这几种都可以获取出正确的Span。</p><p id="0FLMLMQJ">再来看看length…length + 1,-1…0这两种情况。</p><p id="0FLMLMQK">出意外了,这时候就获取不到了。</p><p id="0FLMLMQL">总结一下,来张图就看清楚了。</p><p class="f_center"><img src="https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2021%2F1208%2Ffbfcd4c6j00r3rvi70023d200u000lrg016600uk.jpg&thumbnail=660x&quality=80&type=jpg"/><br/>image-043219<br/></p><p id="0FLMLMQM">红色的范围是不可获取,灰色的范围是可以获取,由此可见,getSpans比setSpan的range要复杂多了。</p><p id="0FLMLMQN">总结一下,对于一个Span,范围是0…Length-1,那么getSpans的range,start…end能获取到Span的条件是,start…end完全落在0…Length-1的左开右闭区间里。</p><p id="0FLMLMQO">最常用的方式,实际上就是:</p><p>Span原理分析</p><p id="0FLMLMQP">我们借助SpannableStringInternal来分析Span具体是如何作用到Text上的。</p><p id="0FLMLM">要想把Span附加到Text上,那么肯定是对Text做了标记,在渲染时,根据标记来做特殊的渲染。</p><p class="f_center"><img src="https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2021%2F1208%2Fe850acbej00r3rvi8000jd200p000b8g00p000b8.jpg&thumbnail=660x&quality=80&type=jpg"/><br/>123davdzz<br/></p><p id="0FLMLMQR">这是Spannable相关的类继承关系。</p><p><ul><li id="0FLMLMSE"></p><p id="0FLMLMQS">对于SpannedString、SpannableString来说,它们是继承的SpannableStringInternal。</p><p></li><li id="0FLMLMSF"></p><p id="0FLMLMQT">Span是否是可变,是通过Spanned(Span不能增删)和Spannable(Span可以增删)接口来区分的。</p><p></li></ul></p><p id="0FLMLMQU">所以核心逻辑都在SpannableStringInternal中,在它的源码中,有几个重要的成员变量:</p><p><ul><li id="0FLMLMSG"></p><p id="0FLMLMQV">mSpans:用来保存具体的Span对象</p><p></li><li id="0FLMLMSH"></p><p id="0FLMLMR0">mSpanData:用来保存每个Span的数据,start、end、flag</p><p></li></ul></p><p id="0FLMLMR1">在mSpanData中,每个Span需要三个元素来控制,所以,mSpanData的长度是3的倍数,每3个元素代表一个Span,从下面这张图就能看的很清楚了。</p><p class="f_center"><img src="https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2021%2F1208%2F17ac9d35j00r3rvi80027d200u000dlg01iw00ou.jpg&thumbnail=660x&quality=80&type=jpg"/><br/>img<br/></p><p id="0FLMLMR2">下面继续来看SpannableStringInternal的构造函数。</p><p id="0FLMLMR3">SpannableStringInternal的构造函数,就是为了初始化上面的成员变量,它有两个来源,一个本身就是SpannableStringInternal,那么直接继承它内部的这些变量即可,另一个是其它类型,就需要重新创建。</p><p></p><p></p><p id="0FLMLMR5"></p><p id="0FLMLMR6">在了解了Text如何保存Span及其数据后,我们来看下getSpans为什么会有上面那么奇葩的设计。</p><p id="0FLMLMR7">原因就在getSpans代码中的check逻辑。</p><p></p><p></p><p></p><p></p><p></p><p id="0FLMLMRC"></p><p id="0FLMLMRD">就是这里的一堆判断逻辑,导致了前面略显奇葩的结果。</p><p id="0FLMLMRE">看到这里,应该就能明白了,我们传入的range(queryStart…queryEnd)和(spanStart…spanEnd)之间究竟是怎么比较的。</p><p id="0FLMLMRF">要通过check,必须依次保证下面的条件(以-1…0为例):</p><p><ul><li id="0FLMLMSI"></p><p id="0FLMLMRG">End &gt;= SpanStart 0 &gt;= 0 true</p><p></li><li id="0FLMLMSJ"></p><p id="0FLMLMRH">Start &lt;= SpanEnd -1 &lt;= 13 true</p><p></li><li id="0FLMLMSK"></p><p id="0FLMLMRI">SpanStart != SpanEnd &amp;&amp; Start != End true</p><p></li><li id="0FLMLMSL"></p><p id="0FLMLMRJ">End != SpanStart 0 != 0 false</p><p></li><li id="0FLMLMSM"></p><p id="0FLMLMRK">SpanEnd != Start 13 != -1 true</p><p></li></ul></p><p id="0FLMLMRL">由此可见,这些条件check的实际上是query的End和SpanStart,以及query的Start和SpanEnd之间的关系。</p><p id="0FLMLMRM">向大家推荐下我的网站 https://xuyisheng.top/ 点击原文一键直达</p><p id="0FLMLMRN">专注 Android-Kotlin-Flutter 欢迎大家访问</p><p><ul><li id="0FLMLMSN"></p><p></li><li id="0FLMLMSO"></p><p></li><li id="0FLMLMSP"></p><p></li><li id="0FLMLMSQ"></p><p></li></ul></p><p id="0FLMLMS8"><strong>本文原创公众号:群英传</strong><strong>,授权转载请联系微信(Tomcat_xu)</strong><strong>,授权后,请在原创发表24小时后转载。</strong></p><p id="0FLMLMS9">&lt; END &gt;</p><p id="0FLMLMSA">作者:徐宜生</p><p id="0FLMLMSB"><strong><strong>更文不易,点个“三连”支持一下</strong></strong><br/></p> 

讯享网
小讯
上一篇 2025-06-05 18:27
下一篇 2025-04-18 08:56

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/142054.html