I have extended EditText view with overridden onDraw method:
@Override
protected void onDraw(Canvas canvas) {
int count = getLineCount();
drawLineNumbers(canvas, count); // here I draw line numbers on canvas,
// like on picture
super.onDraw(canvas);
}
As we know, onDraw method of EditText calls very often, e.g. it calls for each indicator flashing - that's why redrawing all line numbers consume a lot of hardware resources.
Is there efficient method to cache part of canvas and do not redraw it every time? In my case I want to redraw it only when line's count changed. I have already tried save it in Bitmap, but on files with big amount of lines it throwing OutOFMemmory exception.
Any thoughts are welcome.
make a compound custom view:
class NumEditText extends LinearLayout
and add two views: left margin view with line numbers and an. associated EditText
EDIT:
try this skeleton:
public class NumberedEditText extends LinearLayout {
private LineNumbers lineNumbers;
private ET et;
public NumberedEditText(Context context) {
super(context);
setOrientation(HORIZONTAL);
lineNumbers = new LineNumbers(context);
et = new ET(context);
addView(lineNumbers);
addView(et, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
}
class LineNumbers extends View {
private final static String TAG = "NumberedEditText.LineNumbers";
public LineNumbers(Context context) {
super(context);
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
invalidate();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int fixed = 50;
widthMeasureSpec = MeasureSpec.makeMeasureSpec(fixed, MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onDraw(Canvas canvas) {
Log.d(TAG, "onDraw ");
}
}
class ET extends EditText implements TextWatcher {
private final static String TAG = "NumberedEditText.ET";
private Layout layout;
private int cnt;
public ET(Context context) {
super(context);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
addTextChangedListener(this);
layout = getLayout();
cnt = layout.getLineCount();
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
lineNumbers.scrollTo(l, t);
}
@Override
public void onTextChanged(CharSequence text, int start, int before, int after) {
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void afterTextChanged(Editable s) {
if (layout.getLineCount() != cnt) {
cnt = layout.getLineCount();
lineNumbers.invalidate();
}
}
}
}