我正在尝试在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);
答案 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方法中只需在传递的画布上绘制线条等。 我希望这会给你一些想法。