返回介绍

构造方法

发布于 2024-12-23 22:10:47 字数 4400 浏览 0 评论 0 收藏 0

StaticLayout 有多个构造方法,最完整的构造方法(其他构造方法最终也是调用的这个构造方法) 如下所示:

public StaticLayout(CharSequence source, int bufstart, int bufend,
            TextPaint paint, int outerwidth,
            Alignment align, TextDirectionHeuristic textDir,
            float spacingmult, float spacingadd,
            boolean includepad,
            TextUtils.TruncateAt ellipsize, int ellipsizedWidth, int maxLines) {
    super((ellipsize == null)
        ? source
        : (source instanceof Spanned)
          ? new SpannedEllipsizer(source)
          : new Ellipsizer(source),
        paint, outerwidth, align, textDir, spacingmult, spacingadd);

    Builder b = Builder.obtain(source, bufstart, bufend, paint, outerwidth)
      .setAlignment(align)
      .setTextDirection(textDir)
      .setLineSpacing(spacingadd, spacingmult)
      .setIncludePad(includepad)
      .setEllipsizedWidth(ellipsizedWidth)
      .setEllipsize(ellipsize)
      .setMaxLines(maxLines);
    if (ellipsize != null) {
      Ellipsizer e = (Ellipsizer) getText();

      e.mLayout = this;
      e.mWidth = ellipsizedWidth;
      e.mMethod = ellipsize;
      mEllipsizedWidth = ellipsizedWidth;
      mColumns = COLUMNS_ELLIPSIZE;
    } else {
      mColumns = COLUMNS_NORMAL;
      mEllipsizedWidth = outerwidth;
    }

    mLineDirections = ArrayUtils.newUnpaddedArray(Directions.class, 2 * mColumns);
    mLines = new int[mLineDirections.length];
    mMaximumVisibleLineCount = maxLines;

    generate(b, b.mIncludePad, b.mIncludePad);

    Builder.recycle(b);
  }

参数说明:

  • CharSequence source 文本内容
  • int bufstart, int bufend, 开始位置和结束位置
  • TextPaint paint 文本画笔对象
  • int outerwidth 布局宽度,超出宽度换行显示
  • Alignment align 对齐方式,默认是 Alignment.ALIGN_LEFT
  • TextDirectionHeuristic textDir 文本显示方向
  • float spacingmult 行间距倍数,默认是 1
  • float spacingadd 行距增加值,默认是 0
  • boolean includepad 文本顶部和底部是否留白
  • TextUtils.TruncateAt ellipsize 文本省略方式,有 START、MIDDLE、 END、MARQUEE 四种省略方式(其实还有一个 END_SMALL,但是 Google 并未开放出来)。
  • int ellipsizedWidth 省略宽度
  • int maxLines 最大行数

细节分析:

  • 构造方法的开始,在调用父类 Layout 构造方法的时候,判断了文本是否需要省略,如果需要省略,则创建一个 Ellipsizer 对象,Ellipsizer 是 Layout 的嵌套内部类,实现了 CharSequence 和 GetChars 接口。该类就是用来对文本进行省略处理的,具体的处理方法是由其 getChars() 方法完成的。
  • 在创建 Ellipsizer 对象之前,还判断了一下需要显示的文本是否是 Spanned ,如果是的话则创建 SpannedEllipsizer 对象,SpannedEllipsizer 类继承 Ellipsizer ,同时实现了 Spanned 接口。
  • StaticLayout.Builder 对象的创建是通过 Builder.obtain() 方法创建的,在该方法内部可以看到 Builder 对象通过 SynchronizedPool 对象池来管理的,起到缓存的作用,避免 Builder 对象的重复创建,在 StaticLayout 的构造方法的最后也可以看到 Builder.recycle(b) 的调用,回收 Builder 对象。 Builder 的构造方法如下所示:
     private Builder() {
        mNativePtr = nNewBuilder();
      }
    

    其调用了 JNI 层的 nNewBuilder() 方法,新建了一个 LineBreak 对象,并将其指针指向 java 层,赋值给 Builder 对象的 mNativePtr 字段 ,后面调用 native 方法时,均需要将 mNativePtr 作为参数传递过去。

     static jlong nNewBuilder(JNIEnv*, jclass) {
        return reinterpret_cast<jlong>(new LineBreaker);
     }
    
  • mLineDirections 需要结合到后面每行文本处理来理解,这里可以大致说一下,StaticLayout 源码中声明了以下的常量:
     int COLUMNS_NORMAL = 4;
     int COLUMNS_ELLIPSIZE = 6;
     int START = 0;
     int DIR = START;
     int TAB = START;
     int TOP = 1;
     int DESCENT = 2;
     int HYPHEN = 3;
     int ELLIPSIS_START = 4;
     int ELLIPSIS_COUNT = 5;
    

    其中 COLUMNS_NORMAL 和 COLUMNS_ELLIPSIZE 会赋值给全局变量 mColumns,正如你在构造方法中看到的那样,这个在没一行处理时会用到,每一行文本处理时需要记录四个值,start,top,desent,hyphen 值,当文本需要省略时,还需要记录 ellipsis_start 和 ellipsis_count 值,因此正常的 mColumn 值为 4,省略时则是 6,因此 mLineDirections 数组大小始终是 mColumn 的倍数,mLine 数组的大小和其保持一致(从后面的分析来看,mLineDirections 数组的大小没必要这么大)。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文