是否有可能在Android中重载onDraw方法?

时间:2011-08-05 06:55:39

标签: android android-canvas

我正在尝试在Android中的画布上绘制对象。例如,对于填充三角形,我在一个类中定义三角形的值并使用按钮单击,我想从另一个类中调用画布,并在其上显示三角形。

我的问题是我很难将值从类传递到onDraw(Canvas画布)方法。我正在考虑重载该方法。有没有人这样做过?

感谢。

“根据以下回复重新编辑!!”

当我点击另一个班级的按钮时,这是我正在调用的代码。但是,尽管调用了三角形值,但未调用onDraw()方法。我哪里错了?

public class MyView extends View{

Path path = new Path();
Paint paint = new Paint();

public MyView(Context context) {
    super(context);

}

public void setPath(Point a, Point b, Point c){

    path.setFillType(Path.FillType.EVEN_ODD);
    path.moveTo(a.x, b.y);
    Log.d("MYVIEW","pointA" +a.x);
    Log.d("MYVIEW","pointB" +b.y);
    path.lineTo(b.x, b.y);
    path.lineTo(c.x, c.y);
    path.lineTo(a.x, a.y);
    path.close();

    postInvalidate();
}

@Override
protected void onDraw(Canvas canvas) {

     super.onDraw(canvas);

    paint = new Paint(Paint.ANTI_ALIAS_FLAG);

    paint.setStrokeWidth(2);
    paint.setColor(android.graphics.Color.RED);
    paint.setStyle(Paint.Style.FILL_AND_STROKE);
    paint.setAntiAlias(true);

    Log.d("ONDRAW","inside onDraw");
    canvas.drawPath(path, paint);       
}

}

“我如何调用MyView类”

Point pointA = new Point();
        pointA.set(x, y);
        Point pointB = new Point();
        pointB.set(m, n);
        Point pointC = new Point();
        pointC.set(b, c);

        MyView view = new MyView(this.context);

        view.setPath(pointA, pointB, pointC);

3 个答案:

答案 0 :(得分:1)

我认为直接调用onDraw()方法的想法首先是有缺陷的,因为onDraw()系统在需要时调用的方法渲染您的视图,将Canvas传递给它。告诉你希望重新呈现View的系统是通过在该视图上调用invalidate()(或从非UI线程调用postInvalidate())来完成的,然后系统最终会调用该视图的{{ 1}}。

您应该做的是为自定义视图提供对象,该对象包含将影响所绘制内容的数据,或者在自定义视图中创建一些“setter”方法,以便View本身就是对象持有特定数据。这完全取决于您的应用程序。然后你在那个视图上调用onDraw()

上述非常简单的例子:

invalidate()

如果您想要简化它,也可以在setter方法中执行Triangle mTriangle = new Triangle( ... vertices here ... ); mCustomView.setTriangle(mTriangle); mCustomView.invalidate(); Or: mCustomView.setTriangle( ... vertices here ... ); mCustomView.invalidate(); 。这可能是invalidate() TextView方法的工作原理:它将文本设置为变量,然后调用setText()

答案 1 :(得分:0)

这是一种方法:

public class yourDrawingView extends View{

//bla bla bla

int triangle_detail1;
int triangle_detail2; //and all you need to draw the triangle

public void setTriangle(int d1,int d1){ //etc give the function the parameters she needs
    triangle_detail1 = d1;
    triangle_detail2 = d2;
    //ETC

    //finally
    invalidate();
}

protected void onDraw(Canvas canvas){
    super.onDraw(canvas);
    //draw your triangle
}

答案 2 :(得分:0)

自定义视图的缓冲区不是持久的,你必须为每个帧绘制所有内容,而SurfaceView是持久的,但它有两个缓冲区使事情变得复杂。

如果要将所有对象绘制到位图,然后在视图的画布上绘制该位图,则可以轻松地执行所需操作。然后,您可以为对象创建重载方法。

另一种有利于撤消功能的方法是使每个对象成为Trevor建议的类,然后将这些对象添加到ArrayList中。

当onDraw只迭代ArrayList并绘制所有对象时。然后,您可以轻松添加或删除对象。

一个例子:

class Triangle{
 public PointF p1;
 public PointF p2;
 public PointF p3;
 public boolean filled; 
 public int tColor;
 public boolean remove;

  Triangle(PointF p1,PointF p2, PointF p3, boolean filled, int tColor){

   this.p1 = p1;
   this.p2 = p2;
   this.p3 = p3;
   this.filled = filled;
   this tColor = tColor;

  }

}

创建一个三角形并将其添加到arraylist:

ArrayList<Triangle> triangles = new ArrayList<Triangle>();

Triangle triangle = new Triangle(new PointF(1,1),new PointF(2.2f,2.2f),new PointF(3.3f,3.3f), true, Color.BLUE);

triangles.add(triangle);
在视图的onDraw(Canvas画布)中

for (int i = triangles.size() - 1; i >= 0; i--) {

   Triangle triangle = triangles.get(i);
   if (trinagle.remove){
       triangles.remove(i); //remove object if condition met
   }else{
       drawTriangle(triangle, canvas);
   }
}

然后你在drawTriangle方法中只需在传递的画布上绘制线条等。 我希望这会给你一些想法。