android onDraw问题
protected void onDraw(Canvas canvas) {Paint p = new Paint();
p.setColor(Color.RED);
canvas.drawRect(x-25, y-25, x+25, y+25, p);
super.onDraw(canvas);
}
onDraw方法是怎么调用的,和postInvalidate()有什么关系?
为什么有时候运行,会onDraw执行两次??? 是应为组件没加载完吗?
请教~~~~~~~~~~~~~~~~~~ --------------------编程问答-------------------- 你可以从一 个Bitmap得到它的Canvas,进行绘制,也可以自定义一个View,用它的Canvas。不同的时,Android里没有Graphics,而用 Paint代之,当然用法也稍有不同。以下是自定义View的一段代码:
@Override
public void onDraw(Canvas canvas) {
// 首先定义一个paint
Paint paint = new Paint();
// 绘制矩形区域-实心矩形
// 设置颜色
paint.setColor(Color.WHITE);
// 设置样式-填充
paint.setStyle(Style.FILL);
// 绘制一个矩形
canvas.drawRect(new Rect(0, 0, getWidth(), getHeight()), paint);
// 绘空心矩形
// 设置颜色
paint.setColor(Color.RED);
// 设置样式-空心矩形
paint.setStyle(Style.STROKE);
// 绘制一个矩形
canvas.drawRect(new Rect(10, 10, 50, 20), paint);
// 绘文字
// 设置颜色
paint.setColor(Color.GREEN);
// 绘文字
canvas.drawText(str, 30, 30, paint);
// 绘图
// 从资源文件中生成位图
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon);
// 绘图
canvas.drawBitmap(bitmap, 10, 10, paint);
}
以上需要注意的有三点:
1、Android中的Rect和java中的可能稍有区别,前两个参数是左上角的坐标,后两个参数是右下角的坐标(不是宽度和高度);
2、Style.STROKE和Style.FILL外边的像素数是有区别的,这点和java里一样;
3、绘文字时,设置的坐标点为(30,30),但绘出来后你会发现,文字的左上角坐标要比你设置的偏上,不知道是android设置的bug,还是我们有理解到坐标点的意义。
--------------------编程问答-------------------- onDraw是在View初化完成之后开始调用
postInvalidate()是重绘的,也就是调用postInvalidate()后系统会重新调用onDraw方法画一次,
你所说的onDraw方法走二次是什么意思,
你是怎么证明的?是不是你调用了二次postInvalidate()了? --------------------编程问答-------------------- postInvalidate -》 重绘请求
onDraw -> 响应该请求 --------------------编程问答-------------------- 你这个可以去看源码的 写的很清楚 --------------------编程问答-------------------- View里什么也没有,也没调用postInvalidate,只有一个onDraw方法,测试的时候,本来onDraw应该执行一次,有时候会执行两次。
有的说是android组件没加载完,他的组件加载会调用onDraw,所以就执行了两次,我想知道本质是什么,为什么会执行两次,到底系统是怎么调用onDraw的????? --------------------编程问答-------------------- 那只能说你的Activity里的线程有问题了,你初始化的时候就会调用onDraw(),然后每次画图都要调用onDraw ,postInvalidate 一般写在进程中,用来使当前View失效,然后重新调用 onDraw 进行绘图。
你把代码贴全,肯定是逻辑方面有问题,你在检查下, --------------------编程问答-------------------- public class testActivity extends Activity {
myView mv;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mv = new myView(this);
setContentView(mv);
}
}
public class myView extends View{
public myView(Context context) {
super(context);
}
@Override
protected void onDraw(Canvas canvas) {
Paint p = new Paint();
p.setColor(Color.RED);
canvas.drawRect(x-25, y-25, x+25, y+25, p);
super.onDraw(canvas);
}
} --------------------编程问答-------------------- super.onDraw(canvas)这个是不是应该去掉。
new 一个View时,自动调用一个onDraw(),在 onDraw()里再写super.onDraw(canvas),就调用两次了。
下面是我的一段简单的程序段:
protected void onDraw(Canvas can){
int[] colors = new int[20*20];
for(int i = 0;i < 20*20;i++){
colors[i] = 0xff8c00;
}
Bitmap bt = Bitmap.createBitmap(colors, 20, 20, Bitmap.Config.RGB_565);
can.drawColor(Color.BLUE);
can.drawBitmap(bt, 0, 0, null);
} --------------------编程问答-------------------- 我觉得是不是你把 super.onDraw(canvas) 写在了最后的原因,我一般是写在第一行的,这个我没试过,LZ试试 --------------------编程问答-------------------- 呵呵,写了super.onDraw(canvas),有时候也会执行一次。
还有一个问题。
public class myView extends View implements Runnable{
public myView(Context context) {
super(context);
new Thread(this).start();
}
@Override
protected void onDraw(Canvas canvas) {
Paint p = new Paint();
p.setColor(Color.RED);
canvas.drawRect(x-25, y-25, x+25, y+25, p);
super.onDraw(canvas);
}
public void run() {
while(true){
try {
update();//逻辑
postInvalidate();
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
怎么让run和onDraw同步???
--------------------编程问答-------------------- 同步问题,主要是
下面是我的一段代码:
protected void onDraw(Canvas can){
synchronized(this){
for(int i = 0;i < height*width;i++){
colors[i] = col;
}
bt = Bitmap.createBitmap(colors, width,height,Bitmap.Config.RGB_565);
can.drawBitmap(bt, 0, 0, null);
}
}
--------------------编程问答-------------------- 有可能postInvalidate()重绘请求刚一发出,onDraw还没开始执行,run本次循环就结束了,有synchronized 也不会等待onDraw执行。。,有这种情况吗??? --------------------编程问答-------------------- 应该不会吧,按顺序来说,应该是先进入onDraw()的,如果没有synchronized那么,run()不一定会等它onDraw()执行完就开始执行,如果有synchronized,run()肯定得等onDraw()执行完后,再执行。
--------------------编程问答-------------------- 好像是先进入run方法,然后postinvalidate进入onDraw,就会出现那个问题 --------------------编程问答-------------------- 那你不写run()那它会不会进入onDraw()呢 --------------------编程问答-------------------- --------------------编程问答-------------------- 反复调用嘛!!! --------------------编程问答-------------------- 看来很挺复杂的啊! --------------------编程问答-------------------- postInvalidate() 是自动重绘 --------------------编程问答-------------------- 我也遇到onDraw()多运行一次的情况了 lz知道原因么 --------------------编程问答-------------------- 两次三次都正常的 内部做了什么onlayout onmeasure什么的都可能引起重绘 --------------------编程问答-------------------- 执行2次的原因是因为你最后用了父类的ondraw
也就是 super.onDraw
去掉这个就好了 --------------------编程问答-------------------- 这段代码要怎么才能跑起来啊 --------------------编程问答-------------------- --------------------编程问答-------------------- 除 --------------------编程问答-------------------- 你有没有设置横屏开发或者竖屏开发,去测试一下activity有没有两次create
补充:移动开发 , Android