• 安卓TextView的lineHeight*lineCount!=height问题,解决不支持滚动的系统下对多页Text进行分页


    前言

    最近在做运行在墨水屏系统上的程序,由于墨水屏刷新率比较低,所以系统内的软件是不允许滚动和加动画的(在逻辑上)

    这样就导致了平时在普通安卓手机上很简单的程序,在墨水屏系统上就很麻烦,比如多页的应用,普通安卓机直接搞一个ScrollView和RecyclerView就可以了,但墨水屏系统上你需要自己计算每页展示多少内容,然后在进行分页

    旧方式分页

    由于墨水屏的特性,我们要实现一个跨页的TextView,就需要进行分页处理

    ps:为什么不适用自己绘制?因为要兼容富文本

    最开始使用的系统是基于安卓8的,其版本中TextView的行高lineHeight*行数lineCount=TextView的高度,所以最开始的TextView分页算法也很简单:

    先用页面高度/tv行高获得一页能展示多少行,然后通过tv总行数/单页行数计算得到一共多少页,最后在最底部画一个矩形盖住底部最后一行可能展示不全的text就可以了,伪代码如下:

    ps:如果在低版本系统上发现lineHeight*lineCount始终和TextView的height查了固定数值的话,那可能是TextView的默认边距没有去掉,去掉的代码如下:

    includeFontPadding = false

    新方式分页

    后来用了新的安卓11系统后,发现lineHeight*lineCount!=height了,而且后续也上了很多种富文本,所以上面的方式就不太合适了,于是就需要找一种新的分页方式了

    通过扒拉TextView的源码发现,TextView计算Text和布局是通过Layout对象来实现的,于是我们就扒拉Layout的源码

    通过看源码发现包含普通Text和普通富文本的TextView中的Layout对象是StaticLayout,然后发现StaticLayout将其中计算的行位置等的数据保存在了内部变量mLines中,然后通过看源码结合别的博客发现TextView的行位置计算方式有两种:

    分为5线和7线两种(我的推测,如果有问题请大佬们指出)

    其中5线的示意图如下(图片来自承香墨影大佬的博客,侵删): 

     

    七线的没找到图...

     而不管是哪种行位置的计算方式,其实我们并不用管太多,因为Layout方法已经给出了方法让我们获取相应行的相应位置了:

    StaticLayout的getLineTop实现:

     

    虽然没有直接提供行最底部的y轴的值,但是提供了行最顶部的y轴获取的方法getLineTop(line),所以我们只需要拿到下一行的lineTop并减1像素,那就是本行的底部的y轴了,这样我们就可以计算TextView每行的高度并分页了,伪代码如下:

     最后再灵活绘制以下底部矩形盖住显示不全的文字就可以了

    结语

    安卓代码量太大了,每个部分可能都很复杂,如果想搞清楚一个东西,那就直接去看其本质(源码)

    end

     

     

  • 相关阅读:
    Amlogic S905X4 平台上针对HDMI TX(OUT) CEC操作
    卷积神经网络模型之——LeNet网络结构与代码实现
    Golang的GC
    Spring Security笔记
    C/C++空格分开输出 2019年12月电子学会青少年软件编程(C/C++)等级考试一级真题答案解析
    手把手教你实现法玛三因子模型
    Java 实例-如何编译 Java 文件
    Python标准库中的typing
    第一篇【传奇开心果系列】Python深度学习库技术点案例示例:深度解读深度学习在自动驾驶领域的应用
    解决SpringBoot整合Activiti引用JPA:缺少javax.persistence.EntityManagerFactory
  • 原文地址:https://blog.csdn.net/qq_33505109/article/details/125426843