2013-11-27 59 views
0

我已經延長的EditText觀點與重寫的onDraw方法:在自定義視圖中緩存部分畫布。 Android的

@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); 

}

Line number under red

正如我們所知,EditText上的的onDraw方法調用非常頻繁,例如它要求每個指標都閃爍 - 這就是爲什麼重繪所有行號會消耗大量硬件資源的原因。

是否有有效的方法來緩存部分畫布並且不會每次都重繪它?在我的情況下,我只想在行數改變時重新繪製它。我已經嘗試將它保存在位圖中,但是對於具有大量行的文件,它會拋出OutOFMemmory異常。

歡迎任何想法。

回答

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(); 
     } 
    } 
} 
} 
+0

聽起來不錯。但如何同步滾動,線條高度等?你能不能顯示一些代碼片段? – Divers

+1

查看更新的答案 – pskink

+0

謝謝。好主意和解釋。 – Divers