@@ -41,19 +41,20 @@ internal class PreparedLayoutTextView(context: Context) : ViewGroup(context), Re
4141 private var clickableSpans: List <ClickableSpan > = emptyList()
4242 private var selection: TextSelection ? = null
4343
44- public var layout : Layout ? = null
44+ public var preparedLayout : PreparedLayout ? = null
4545 set(value) {
4646 if (field != value) {
4747 val lastSelection = selection
4848 if (lastSelection != null ) {
49- if (value != null && field?.text.toString() == value.text.toString()) {
50- value.getSelectionPath(lastSelection.start, lastSelection.end, lastSelection.path)
49+ if (value != null && field?.layout?.text.toString() == value.layout.text.toString()) {
50+ value.layout.getSelectionPath(
51+ lastSelection.start, lastSelection.end, lastSelection.path)
5152 } else {
5253 clearSelection()
5354 }
5455 }
5556
56- clickableSpans = value?.text?.let { filterClickableSpans(it) } ? : emptyList()
57+ clickableSpans = value?.layout?. text?.let { filterClickableSpans(it) } ? : emptyList()
5758
5859 field = value
5960 invalidate()
@@ -73,7 +74,7 @@ internal class PreparedLayoutTextView(context: Context) : ViewGroup(context), Re
7374 public @ColorInt var selectionColor: Int? = null
7475
7576 public val text: CharSequence?
76- get() = layout?.text
77+ get() = preparedLayout?. layout?.text
7778
7879 init {
7980 initView()
@@ -84,7 +85,7 @@ internal class PreparedLayoutTextView(context: Context) : ViewGroup(context), Re
8485 private fun initView () {
8586 clickableSpans = emptyList()
8687 selection = null
87- layout = null
88+ preparedLayout = null
8889 }
8990
9091 public fun recycleView (): Unit {
@@ -101,17 +102,17 @@ internal class PreparedLayoutTextView(context: Context) : ViewGroup(context), Re
101102 super .onDraw(canvas)
102103 canvas.translate(paddingLeft.toFloat(), paddingTop.toFloat())
103104
104- val textLayout = layout
105- if (textLayout != null ) {
105+ val layout = preparedLayout?. layout
106+ if (layout != null ) {
106107 if (selection != null ) {
107108 selectionPaint.setColor(
108109 selectionColor ? : DefaultStyleValuesUtil .getDefaultTextColorHighlight(context))
109110 }
110111
111112 if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .UPSIDE_DOWN_CAKE ) {
112- Api34Utils .draw(textLayout , canvas, selection?.path, selectionPaint)
113+ Api34Utils .draw(layout , canvas, selection?.path, selectionPaint)
113114 } else {
114- textLayout .draw(canvas, selection?.path, selectionPaint, 0 )
115+ layout .draw(canvas, selection?.path, selectionPaint, 0 )
115116 }
116117 }
117118 }
@@ -121,21 +122,21 @@ internal class PreparedLayoutTextView(context: Context) : ViewGroup(context), Re
121122 }
122123
123124 public fun setSelection (start : Int , end : Int ) {
124- val textLayout = checkNotNull(layout)
125- if (start < 0 || end > textLayout .text.length || start >= end) {
125+ val layout = checkNotNull(preparedLayout).layout
126+ if (start < 0 || end > layout .text.length || start >= end) {
126127 throw IllegalArgumentException (
127- " setSelection start and end are not in valid range. start: $start , end: $end , text length: ${textLayout .text.length} " )
128+ " setSelection start and end are not in valid range. start: $start , end: $end , text length: ${layout .text.length} " )
128129 }
129130
130131 val textSelection = selection
131132 if (textSelection == null ) {
132133 val selectionPath = Path ()
133- textLayout .getSelectionPath(start, end, selectionPath)
134+ layout .getSelectionPath(start, end, selectionPath)
134135 selection = TextSelection (start, end, selectionPath)
135136 } else {
136137 textSelection.start = start
137138 textSelection.end = end
138- textLayout .getSelectionPath(start, end, textSelection.path)
139+ layout .getSelectionPath(start, end, textSelection.path)
139140 }
140141
141142 invalidate()
@@ -171,9 +172,9 @@ internal class PreparedLayoutTextView(context: Context) : ViewGroup(context), Re
171172 clearSelection()
172173 clickableSpan.onClick(this )
173174 } else if (action == MotionEvent .ACTION_DOWN ) {
174- val textLayout = checkNotNull(layout)
175- val start = (textLayout .text as Spanned ).getSpanStart(clickableSpan)
176- val end = (textLayout .text as Spanned ).getSpanEnd(clickableSpan)
175+ val layout = checkNotNull(preparedLayout).layout
176+ val start = (layout .text as Spanned ).getSpanStart(clickableSpan)
177+ val end = (layout .text as Spanned ).getSpanEnd(clickableSpan)
177178 setSelection(start, end)
178179 }
179180
@@ -205,19 +206,19 @@ internal class PreparedLayoutTextView(context: Context) : ViewGroup(context), Re
205206 }
206207
207208 private fun getTextOffsetAt (x : Int , y : Int ): Int {
208- val textLayout = layout ? : return - 1
209- val line = textLayout .getLineForVertical(y)
209+ val layout = preparedLayout?. layout ? : return - 1
210+ val line = layout .getLineForVertical(y)
210211
211212 val left: Float
212213 val right: Float
213214
214- if (textLayout .alignment == Layout .Alignment .ALIGN_CENTER ) {
215+ if (layout .alignment == Layout .Alignment .ALIGN_CENTER ) {
215216 /* *
216217 * [Layout#getLineLeft] and [Layout#getLineRight] properly account for paragraph margins on
217218 * centered text.
218219 */
219- left = textLayout .getLineLeft(line)
220- right = textLayout .getLineRight(line)
220+ left = layout .getLineLeft(line)
221+ right = layout .getLineRight(line)
221222 } else {
222223 /* *
223224 * [Layout#getLineLeft] and [Layout#getLineRight] do NOT properly account for paragraph
@@ -229,19 +230,19 @@ internal class PreparedLayoutTextView(context: Context) : ViewGroup(context), Re
229230 * [Layout#getLineMax] gives the extent *plus* the leading margin, so we can figure out the
230231 * rest from there.
231232 */
232- val rtl = textLayout .getParagraphDirection(line) == Layout .DIR_RIGHT_TO_LEFT
233+ val rtl = layout .getParagraphDirection(line) == Layout .DIR_RIGHT_TO_LEFT
233234 left =
234- if (rtl) (textLayout .width - textLayout .getLineMax(line))
235- else textLayout .getParagraphLeft(line).toFloat()
236- right = if (rtl) textLayout .getParagraphRight(line).toFloat() else textLayout .getLineMax(line)
235+ if (rtl) (layout .width - layout .getLineMax(line))
236+ else layout .getParagraphLeft(line).toFloat()
237+ right = if (rtl) layout .getParagraphRight(line).toFloat() else layout .getLineMax(line)
237238 }
238239
239240 if (x < left || x > right) {
240241 return - 1
241242 }
242243
243244 return try {
244- textLayout .getOffsetForHorizontal(line, x.toFloat())
245+ layout .getOffsetForHorizontal(line, x.toFloat())
245246 } catch (e: ArrayIndexOutOfBoundsException ) {
246247 // This happens for bidi text on Android 7-8.
247248 // See
0 commit comments