我使用重写的 onDraw 方法扩展了 EditText 视图:
@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);
}
众所周知,EditText的onDraw方法经常调用,例如它要求每个指示灯闪烁 - 这就是重绘所有行号消耗大量硬件资源的原因。
是否有有效的方法来缓存部分画布而不是每次都重绘它?在我的情况下,我想只在行数改变时重绘它。我已经尝试将其保存在Bitmap中,但是对于行数较多的文件,它会抛出 OutOFMemmory 异常。
欢迎任何想法。
答案 0 :(得分:1)
制作复合自定义视图:
class NumEditText extends LinearLayout
并添加两个视图:带有行号的左边距视图和一个。关联的EditText
编辑:
尝试这个骨架:
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();
}
}
}
}