在自定义视图中缓存画布的一部分。 Android

问题描述 投票:0回答:1

我用覆盖的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);

}

<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS9DdERQSC5wbmcifQ==” alt =“红色下的行号”>

据我们所知,EditText的onDraw方法经常调用,例如它要求每个指示灯闪烁-这就是为什么重新绘制所有行号会消耗大量硬件资源的原因。

是否有一种有效的方法来缓存画布的一部分并且不每次都重新绘制?就我而言,我只想在行数改变时才重画它。我已经尝试过将其保存在位图中,但是在行数很多的文件上会抛出OutOFMemmory异常。

任何想法都欢迎。

android android-edittext android-canvas ondraw
1个回答
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();
        }
    }
}
}
© www.soinside.com 2019 - 2024. All rights reserved.