1313import android .widget .EditText ;
1414
1515import androidx .annotation .NonNull ;
16- import androidx .appcompat .widget .AppCompatTextView ;
1716
1817@ SuppressWarnings ("UnusedReturnValue" )
19- public class LineNumbersTextView extends AppCompatTextView {
18+ public class LineNumbersView extends View {
2019 private EditText editText ;
2120 private LineNumbersDrawer lineNumbersDrawer ;
2221 private boolean lineNumbersEnabled ;
2322
24- public LineNumbersTextView (Context context ) {
23+ public LineNumbersView (Context context ) {
2524 super (context );
2625 }
2726
28- public LineNumbersTextView (Context context , AttributeSet attrs ) {
27+ public LineNumbersView (Context context , AttributeSet attrs ) {
2928 super (context , attrs );
3029 }
3130
32- public LineNumbersTextView (Context context , AttributeSet attrs , int defStyleAttr ) {
31+ public LineNumbersView (Context context , AttributeSet attrs , int defStyleAttr ) {
3332 super (context , attrs , defStyleAttr );
3433 }
3534
3635 @ Override
37- protected void onVisibilityChanged (View changedView , int visibility ) {
36+ protected void onAttachedToWindow () {
37+ super .onAttachedToWindow ();
38+ setWidth (0 ); // Initial width
39+ }
40+
41+ @ Override
42+ protected void onVisibilityChanged (@ NonNull View changedView , int visibility ) {
3843 super .onVisibilityChanged (changedView , visibility );
3944 if (isLineNumbersEnabled () && visibility == View .VISIBLE ) {
4045 refresh ();
4146 }
4247 }
4348
4449 @ Override
45- protected void onDraw (Canvas canvas ) {
50+ protected void onDraw (@ NonNull Canvas canvas ) {
4651 super .onDraw (canvas );
4752 if (lineNumbersEnabled ) {
4853 lineNumbersDrawer .draw (canvas );
4954 }
5055 }
5156
57+ /**
58+ * Refresh LineNumbersView.
59+ */
5260 public void refresh () {
53- setText ( "" ); // To activate LineNumbersTextView refresh
61+ invalidate ();
5462 if (getWidth () == 0 ) {
5563 lineNumbersDrawer .getEditText ().postInvalidate ();
5664 }
@@ -64,6 +72,11 @@ public void setup(final @NonNull EditText editText) {
6472 this .lineNumbersDrawer = null ;
6573 }
6674
75+ public void setWidth (int width ) {
76+ getLayoutParams ().width = width ;
77+ requestLayout ();
78+ }
79+
6780 public void setLineNumbersEnabled (final boolean enabled ) {
6881 lineNumbersEnabled = enabled ;
6982
@@ -76,7 +89,7 @@ public void setLineNumbersEnabled(final boolean enabled) {
7689 if (lineNumbersDrawer == null ) {
7790 return ;
7891 }
79- lineNumbersDrawer .done ();
92+ lineNumbersDrawer .cleanup ();
8093 }
8194 refresh ();
8295 }
@@ -87,7 +100,7 @@ public boolean isLineNumbersEnabled() {
87100
88101 static class LineNumbersDrawer {
89102 private final EditText editText ;
90- private final LineNumbersTextView textView ;
103+ private final LineNumbersView lineNumbersView ;
91104
92105 private final Paint paint = new Paint ();
93106
@@ -96,8 +109,8 @@ static class LineNumbersDrawer {
96109 private static final int EDITOR_PADDING_LEFT = 8 ;
97110 private final int ORIGINAL_PADDING_LEFT ;
98111
99- private final Rect visibleArea = new Rect ();
100- private final Rect lineNumbersArea = new Rect ();
112+ private final Rect visibleRect = new Rect ();
113+ private final Rect lineNumbersRect = new Rect ();
101114
102115 private int fenceX ;
103116 private int numberX ;
@@ -123,7 +136,7 @@ public void onTextChanged(CharSequence s, int start, int before, int count) {
123136 @ Override
124137 public void afterTextChanged (Editable editable ) {
125138 if (isLayoutLineCountChanged () || isMaxNumberChanged ()) {
126- textView .refresh ();
139+ lineNumbersView .refresh ();
127140 }
128141 }
129142 };
@@ -136,14 +149,14 @@ public void onScrollChanged() {
136149 final long time = System .currentTimeMillis ();
137150 if (time - lastTime > 125 ) {
138151 lastTime = time ;
139- textView .refresh ();
152+ lineNumbersView .refresh ();
140153 }
141154 }
142155 };
143156
144- public LineNumbersDrawer (final @ NonNull EditText editText , final @ NonNull LineNumbersTextView textView ) {
157+ public LineNumbersDrawer (final @ NonNull EditText editText , final @ NonNull LineNumbersView lineNumbersView ) {
145158 this .editText = editText ;
146- this .textView = textView ;
159+ this .lineNumbersView = lineNumbersView ;
147160 ORIGINAL_PADDING_LEFT = editText .getPaddingLeft ();
148161 paint .setColor (0xFF999999 );
149162 paint .setTextAlign (Paint .Align .RIGHT );
@@ -154,15 +167,15 @@ public EditText getEditText() {
154167 }
155168
156169 private boolean isOutOfLineNumbersArea () {
157- final int margin = (int ) (visibleArea .height () * 0.5f );
158- final int top = visibleArea .top - margin ;
159- final int bottom = visibleArea .bottom + margin ;
170+ final int margin = (int ) (visibleRect .height () * 0.5f );
171+ final int top = visibleRect .top - margin ;
172+ final int bottom = visibleRect .bottom + margin ;
160173
161- if (top < lineNumbersArea .top || bottom > lineNumbersArea .bottom ) {
174+ if (top < lineNumbersRect .top || bottom > lineNumbersRect .bottom ) {
162175 // Set line numbers area
163176 // height of line numbers area = (1.5 + 1 + 1.5) * height of visible area
164- lineNumbersArea .top = top - visibleArea .height ();
165- lineNumbersArea .bottom = bottom + visibleArea .height ();
177+ lineNumbersRect .top = top - visibleRect .height ();
178+ lineNumbersRect .bottom = bottom + visibleRect .height ();
166179 return true ;
167180 } else {
168181 return false ;
@@ -262,7 +275,8 @@ private void setRefreshOnScrollChanged(final boolean enabled) {
262275 public void prepare () {
263276 setLineTracking (true );
264277 setRefreshOnScrollChanged (true );
265- textView .setVisibility (VISIBLE );
278+ lineNumbersView .setWidth (0 );
279+ lineNumbersView .setVisibility (VISIBLE );
266280 editText .setPadding (EDITOR_PADDING_LEFT , editText .getPaddingTop (), editText .getPaddingRight (), editText .getPaddingBottom ());
267281 }
268282
@@ -272,7 +286,7 @@ public void prepare() {
272286 * @param canvas The canvas on which the line numbers will be drawn.
273287 */
274288 public void draw (final Canvas canvas ) {
275- if (!editText .getLocalVisibleRect (visibleArea )) {
289+ if (!editText .getLocalVisibleRect (visibleRect )) {
276290 return ;
277291 }
278292
@@ -286,7 +300,7 @@ public void draw(final Canvas canvas) {
286300 if (isTextSizeChanged () || isMaxNumberDigitsChanged ()) {
287301 numberX = NUMBER_PADDING_LEFT + (int ) paint .measureText (String .valueOf (maxNumber ));
288302 fenceX = numberX + NUMBER_PADDING_RIGHT ;
289- textView .setWidth (fenceX + 1 );
303+ lineNumbersView .setWidth (fenceX + 1 );
290304 }
291305
292306 // If current visible area is out of current line numbers area,
@@ -299,7 +313,7 @@ public void draw(final Canvas canvas) {
299313 }
300314
301315 // Draw right border of the fence
302- canvas .drawLine (fenceX , lineNumbersArea .top , fenceX , lineNumbersArea .bottom , paint );
316+ canvas .drawLine (fenceX , lineNumbersRect .top , fenceX , lineNumbersRect .bottom , paint );
303317
304318 // Draw line numbers
305319 int i = startLine [0 ];
@@ -308,7 +322,7 @@ public void draw(final Canvas canvas) {
308322 final int count = layout .getLineCount ();
309323 final int offsetY = editText .getPaddingTop ();
310324
311- if (y > lineNumbersArea .top ) {
325+ if (y > lineNumbersRect .top ) {
312326 if (invalid ) {
313327 invalid = false ;
314328 startLine [0 ] = i ;
@@ -322,14 +336,14 @@ public void draw(final Canvas canvas) {
322336 for (; i < count ; i ++) {
323337 if (text .charAt (layout .getLineStart (i ) - 1 ) == '\n' ) {
324338 y = layout .getLineBaseline (i );
325- if (y > lineNumbersArea .top ) {
339+ if (y > lineNumbersRect .top ) {
326340 if (invalid ) {
327341 invalid = false ;
328342 startLine [0 ] = i ;
329343 startLine [1 ] = number ;
330344 }
331345 canvas .drawText (String .valueOf (number ), numberX , y + offsetY , paint );
332- if (y > lineNumbersArea .bottom ) {
346+ if (y > lineNumbersRect .bottom ) {
333347 break ;
334348 }
335349 }
@@ -341,12 +355,11 @@ public void draw(final Canvas canvas) {
341355 /**
342356 * Reset some states related line numbers.
343357 */
344- public void done () {
358+ public void cleanup () {
345359 setLineTracking (false );
346360 setRefreshOnScrollChanged (false );
347361 maxNumberDigits = 0 ;
348- textView .setWidth (0 );
349- textView .setVisibility (GONE );
362+ lineNumbersView .setVisibility (GONE );
350363 editText .setPadding (ORIGINAL_PADDING_LEFT , editText .getPaddingTop (), editText .getPaddingRight (), editText .getPaddingBottom ());
351364 }
352365 }
0 commit comments