读书人

android上画图不显示的有关问题

发布时间: 2012-11-12 12:31:58 作者: rapoo

android下画图不显示的问题
我在程序中使用android的canvas进行画图,想把画图的功能稍微封装一下,让外面的类可以调用,但是发现,我使用canvas画图的时候在类的OnDraw函数当中可以正常显示,但是一旦把画图封装成一个函数让外面的类来调用,却始终看不到画的图。我的代码如下
MainActivity.java

Java code
public class MainActivity extends Activity {        FrameLayout linearLayout;        @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        linearLayout=(FrameLayout)findViewById(R.id.linearLayout_canvas);        final MyCanvas myCanvas=new MyCanvas(this);        linearLayout.addView(myCanvas);        Button drawCircle=(Button)findViewById(R.id.drawCircle);        Button drawLine =(Button)findViewById(R.id.drawLine);        drawCircle.setOnClickListener(new View.OnClickListener() {                        public void onClick(View v) {                // TODO Auto-generated method stub                myCanvas.drawCircle(100, 100, 100);            }        });                drawLine.setOnClickListener(new View.OnClickListener() {                        public void onClick(View v) {                // TODO Auto-generated method stub                myCanvas.drawLine(200, 200, 300, 300);                            }        });           }    @Override    public boolean onCreateOptionsMenu(Menu menu) {        getMenuInflater().inflate(R.menu.activity_main, menu);        return true;    }    }

MyCanvas.java
Java code
public class MyCanvas extends View{        private Canvas myCanvas;    private Paint myPaint=new Paint();        public MyCanvas(Context context) {        super(context);        // TODO Auto-generated constructor stub        this.setOnTouchListener(new View.OnTouchListener() {                        public boolean onTouch(View v, MotionEvent event) {                // TODO Auto-generated method stub                switch (event.getAction()) {                case MotionEvent.ACTION_DOWN:                    drawCircle(event.getX(), event.getY(), 20);                    break;                default:                    break;                }                return true;            }        });    }    public MyCanvas(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        // TODO Auto-generated constructor stub    }    public MyCanvas(Context context, AttributeSet attrs) {        super(context, attrs);        // TODO Auto-generated constructor stub    }    @Override    protected void onDraw(Canvas canvas) {        // TODO Auto-generated method stub        super.onDraw(canvas);        this.myCanvas=canvas;    }        /**     * 设置画笔默认样式     */    public void setPaintDefaultStyle(){        myPaint.setAntiAlias(true);        myPaint.setColor(Color.BLACK);        myPaint.setStyle(Paint.Style.STROKE);        myPaint.setStrokeWidth(2);    }            /**     * 画圆     * @param x x坐标     * @param y    y坐标     * @param radius    圆的半径     */    public void drawCircle(float x,float y,float radius){        setPaintDefaultStyle();        myCanvas.drawCircle(x, y, radius, myPaint);//        invalidate();    }        /**     * 画一条直线     * @param fromX 起点x坐标     * @param fromY    起点Y坐标     * @param toX    终点X坐标     * @param toY    终点Y坐标     */    public void drawLine(float fromX,float fromY,float toX,float toY){        setPaintDefaultStyle();        Path linePath=new Path();        linePath.moveTo(fromX, fromY);        linePath.lineTo(toX, toY);        linePath.close();        myCanvas.drawPath(linePath, myPaint);//        invalidate();    }    }

在上面的两个代码当中,我调试的时候相应的执行函数都被执行过,比如说我用MainActivity调用drawLine函数,可以在调试的时候看到这个函数确实被执行了,但是画面就是不显示。我后面想加上invalidate函数重绘一下,调试的时候可以看到onDraw函数确实被执行了,但是还是没有画面显示,不知道怎么回事,忘各位指点迷津啊~



[解决办法]
可以看一下view的源代码,
public class View implements Drawable.Callback, KeyEvent.Callback, AccessibilityEventSource {
//....
public void draw(Canvas canvas) {
//....
onDraw(canvas);
//....
}

/**
* Implement this to do your drawing.
*
* @param canvas the canvas on which the background will be drawn
*/
protected void onDraw(Canvas canvas) {
}
}

我们在自己的继承类中多态实现了onDraw()
这样流程就清楚了,我们知道view只有在onMeasure和onLayout调用,或者手动调用invalidate方法时才会开始重绘。来说一说楼主的逻辑吧
如果将drawLine方法直接放在onDraw里面,此时在第一次加载view或者手动调用invalidate()时都会发生绘制,如楼主所说可以看到线条,
但是如果按照楼主第二种方法手动调用drawLine(),此时没有发生重绘操作,即父view的draw()根本就没有发生回调,怎么可能有图形出现呢。
绘图不是只要在canvas中画一下就能完事儿的,每次绘图都涉及到背景重绘,图层等很多元素,所以单独drawLine一下是没有用的

读书人网 >Android

热点推荐