2011年8月9日 星期二

invalidate 部分畫面

寫了一個程式, 自己設計了一個view, MyView 繼承至View
在畫圖(onDraw())時, 座標的計算是相對座標, 例如, (0,0) 對應的是畫布的左上角, 但是在整個螢幕上, 並不是左上角。
在整個螢幕上,有二行,一行是系統的狀態行,一行是標題行。
找Google, 很容易可以找到指令。

Rect rectgle= new Rect();
Window window= getWindow();
window.getDecorView().getWindowVisibleDisplayFrame(rectgle);
int StatusBarHeight= rectgle.top;
int contentViewTop=
window.findViewById(Window.ID_ANDROID_CONTENT).getTop();
int TitleBarHeight= contentViewTop - StatusBarHeight;

重點是:這些指令必須在view所在的thread中執行, 因此,如果你想要在Activity中執行,必須加上:

MyView.post(new Runnable() {
@Override
public void run() {
/* 將執行程式放在此處 */
}
});

另外一個方式是,直接放在View的onDraw()函數。
看起來好像可以用了, 但是,
Invalidate()會調用onDraw(), 沒有錯,
但限定範圍的Invalidate(範圍), 產生的結果卻很怪異,
通常前幾次 (幾乎都是三次,也出現過部分是一次),會畫整個畫面,如同invalidate() (没有參數),造成整個畫布的重劃,這些次數過後,就正常了,只重劃指定的部分。改成postInvalidate()也是相同,只是怪。
指定的操作是:
  1. 設定繪畫方法為call back
  2. 執行invalidate調用onDraw
  3. onDraw呼叫設定的繪畫方法

/**
* Show item is checked
* @param canvas
* @param date
* @param id
*/
public void ShowChecked(Canvas canvas, int date, int id) {
XY xy=this.getXY(date, id);
if(checked==null) {
checked = BitmapFactory.decodeResource(getResources(),R.drawable.yes);
checked = Bitmap.createScaledBitmap(checked,(int)(unit_width*0.8),(int)(unit_height*0.8), true);
}
canvas.drawBitmap(checked, xy.x+(unit_width*0.1f), xy.y, new Paint());
}
/**
* Call the ShowChecked from outside
* @param date
* @param id
*/
public void ShowChecked(final int date, final int id) {
action.add(new Action() {
@Override
public void GoDraw(Canvas canvas) {
ShowChecked(canvas,date,id);
}
});
this.invalidate(region(date,id));
}

沒有留言:

張貼留言