Skip to content

Instantly share code, notes, and snippets.

@francisnnumbi
Created May 16, 2017 08:32
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save francisnnumbi/37ff8a3189a194b939d58d4ad79bf694 to your computer and use it in GitHub Desktop.
Save francisnnumbi/37ff8a3189a194b939d58d4ad79bf694 to your computer and use it in GitHub Desktop.
implementing an EditText with line number on the left. What is new is: - get/set line number margin gap - set line number visible - set line number color Everything is done in the overridden onDraw() method.
import android.widget.*;
import android.util.*;
import android.content.*;
import android.graphics.*;
/**
* the simple implementation of an EditText where each line is numbered on the left
*/
public class LineNumberedEditText extends EditText {
/** whether to set the lines visible or not */
private boolean lineNumberVisible = false;
private Rect _rect;
private Paint lpaint;
/** the gap between the line number and the left margin of the text */
private int lineNumberMarginGap = 2;
/**
*the difference between line text size and the normal text size.
* line text size is preferabl smaller than the normal text size
*/
protected int LINE_NUMBER_TEXTSIZE_GAP = 2;
public LineNumberedEditText (Context context, AttributeSet attrs) {
super(context, attrs);
_rect = new Rect();
lpaint = new Paint();
lpaint.setAntiAlias(true);
lpaint.setStyle(Paint.Style.FILL);
lpaint.setColor(Color.BLACK);
lpaint.setTextSize(getTextSize() - LINE_NUMBER_TEXTSIZE_GAP);
}
public void setLineNumberMarginGap(int lineNumberMarginGap) {
this.lineNumberMarginGap = lineNumberMarginGap;
}
public int getLineNumberMarginGap() {
return lineNumberMarginGap;
}
public void setLineNumberVisible(boolean lineNumberVisible) {
this.lineNumberVisible = lineNumberVisible;
}
public boolean isLineNumberVisible() {
return lineNumberVisible;
}
public void setLineNumberTextColor(int textColor) {
lpaint.setColor(textColor);
}
public int getLineNumberTextColor() {
return lpaint.getColor();
}
@Override
protected void onDraw(Canvas canvas) {
// TODO: Implement this method
if (lineNumberVisible) {
//set the size in case it changed after the last update
lpaint.setTextSize(getTextSize() - LINE_NUMBER_TEXTSIZE_GAP);
int baseLine = getBaseline();
String t = "";
for (int i = 0; i < getLineCount(); i++) {
t = "" + (i + 1);
canvas.drawText(t, _rect.left, baseLine, lpaint);
baseLine += getLineHeight();
}
// set padding again, adjusting only the left padding
setPadding((int)lpaint.measureText(t) + lineNumberMarginGap, getPaddingTop(),
getPaddingRight(), getPaddingBottom());
}
super.onDraw(canvas);
}
}
@Youcef-bou
Copy link

Nice 👍, how to change color like code editor, like this.
Uploading wp-image-1611135186.png…

@t-arn
Copy link

t-arn commented Jan 17, 2023

I'm very excited about this class! I'm trying to create a code editor widget for Toga (www.beeware.org) and this class might just be what I need for the Android implementation layer!

I have 3 questions:

Am I allowed to use your code to create the above mentioned Toga widget?

From what I see, this class generates line numbers for all lines. Won't that be slow when there are many lines? How could the code be adapted to just generate line numbers for the visible lines?

When there is no line wrapping, the numbering is just fine as it is. But when line wrapping is active, I don't want a new line number for the wrapped parts. I only want a new line number when the previous display line ended with a newline character "\n". How can this be achieved?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment