- CompoundButton 源码分析
- LinearLayout 源码分析
- SearchView 源码解析
- LruCache 源码解析
- ViewDragHelper 源码解析
- BottomSheets 源码解析
- Media Player 源码分析
- NavigationView 源码解析
- Service 源码解析
- Binder 源码分析
- Android 应用 Preference 相关及源码浅析 SharePreferences 篇
- ScrollView 源码解析
- Handler 源码解析
- NestedScrollView 源码解析
- SQLiteOpenHelper/SQLiteDatabase/Cursor 源码解析
- Bundle 源码解析
- LocalBroadcastManager 源码解析
- Toast 源码解析
- TextInputLayout
- LayoutInflater 和 LayoutInflaterCompat 源码解析
- TextView 源码解析
- NestedScrolling 事件机制源码解析
- ViewGroup 源码解析
- StaticLayout 源码分析
- AtomicFile 源码解析
- AtomicFile 源码解析
- Spannable 源码分析
- Notification 之 Android 5.0 实现原理
- CoordinatorLayout 源码分析
- Scroller 源码解析
- SwipeRefreshLayout 源码分析
- FloatingActionButton 源码解析
- AsyncTask 源码分析
- TabLayout 源码解析
文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
构造方法
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
行间距倍数,默认是 1float spacingadd
行距增加值,默认是 0boolean 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论