这是我第一次在这里提问。我的Android应用程序有这个问题。 我想在我的自定义视图类中创建不同的绘制方法。有三个按钮对应3种不同的形状。按下按钮时,它将绘制其形状。但是,当我尝试从MainActivity调用自定义绘图时,应用程序崩溃,让我测试它。
MainActivity
import com.example.shapes.view.ShapesView;
public class MainActivity extends Activity {
ShapesView shapesview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
shapesview = (ShapesView) findViewById(R.id.ShapesViewID);
shapesview.DrawRectangle();
}
ShapesView
public class ShapesView extends View{
Canvas canvas;
public ShapesView(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.canvas = canvas;
}
public void DrawRectangle() {
Paint mypaint = new Paint();
mypaint.setColor(Color.BLUE);
canvas.drawRect(30, 30, 200, 200, mypaint);
}
}
我的XML布局文件
<com.example.shapes.view.ShapesView
android:id="@+id/ShapesViewID"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content" />`
请帮忙!非常感谢你!
答案 0 :(得分:2)
如果我理解你的问题,你需要一个自定义视图(一个按钮),它将根据某些事件以不同的方式绘制自己。如果是这种情况,那么您需要尊重Android关于视图绘制的指南,看看here。
现在,您的案例的一个可能的解决方案是设置关于视图状态的某种标志,然后在准备好绘制时使用该标志。例如,您可以这样做:
public class ShapesView extends View{
public int state = 0;
public ShapesView(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);
if (state == 1) {
Paint mypaint = new Paint();
mypaint.setColor(Color.BLUE);
canvas.drawRect(30, 30, 200, 200, mypaint);
}
}
然后,只要您需要从活动中绘制视图,就可以使用以下内容:
myview.state = 1;
myview.invalidate();
在您的代码中,您正在执行的是在活动的onCreate期间调用视图函数,而onCreate会依次尝试使用空画布,因为在此期间未调用视图的onDraw方法。此外,正如其他人指出的那样,你不能在onDraw方法之外使用画布对象。
希望这会有所帮助......
答案 1 :(得分:1)
我用以下内容更改了代码。
public class ShapesView extends View {
Paint mypaint;
public ShapesView(Context context, AttributeSet attrs) {
super(context, attrs);
mypaint = new Paint();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mypaint.setColor(Color.BLUE);
canvas.drawRect(30, 30, 200, 200, mypaint);
}
}
如果您想绘图,请致电shapesview.invalidate();
答案 2 :(得分:1)
查看方法的名称onDraw()
而不是getCanvas()
。该文档也未对所提供的Canvas
提出任何声明。
完成onDraw()
后,可以处理canvas
,其位图/缓冲区可以重新循环,谁知道。
因此,在此方法之外使用Canvas是不安全的。画出你想要的东西,但只能在onDraw()
方法中。
如果您想触发视图重新绘制,请在其他时间拨打invalidate()
。
查看类以呈现任何形状:
public class ShapeView extends View {
private Paint mPaint;
private ShapeRenderer mRenderer;
public ShapeView(Context context) {
super(context);
init();
}
public ShapeView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public ShapeView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init(){
mPaint = new Paint();
}
public void setPaintColor(int color){
mPaint.setColor(color);
}
public void setPaintStrokeWidth(float width){
mPaint.setStrokeWidth(width);
}
public void setRenderer(ShapeRenderer renderer) {
mRenderer = renderer;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if(mRenderer != null){
mRenderer.drawShape(canvas,mPaint);
}
}
public static interface ShapeRenderer{
public void drawShape(Canvas canvas, Paint paint);
}
}
绘制矩形的类:
public class RectRenderer implements ShapeView.ShapeRenderer {
@Override
public void drawShape(Canvas canvas, Paint paint) {
canvas.drawRect(0,0,100,100,paint);
}
}
在运行时绘制形状:
myShapeView.setPaintColor(Color.GREEN);
myShapeView.setPaintStroke(5f);
myShapeView.setRenderer(new RectRenderer());
myShapeView.invalidate();
答案 3 :(得分:0)
我认为你必须重新设计你的组件,所以它可以在onDraw方法中绘制自己。如果你需要一些必须包含Canvas的类,你可以尝试这样做。
class Drawer {
private Canvas canvas;
public Drawer(Canvas canvas) {
this.canvas = canvas;
}
public void DrawRectangle() {
Paint mypaint = new Paint();
mypaint.setColor(Color.BLUE);
canvas.drawRect(30, 30, 200, 200, mypaint);
}
}
在您的自定义视图中,您可以执行以下操作。
public class ShapesView extends View{
public ShapesView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
Drawer drawer = new Drawer(canvas);
drawer.DrawRectangle();
}
public void DrawRectangle() {
Paint mypaint = new Paint();
mypaint.setColor(Color.BLUE);
canvas.drawRect(30, 30, 200, 200, mypaint);
}
}