1

ここで質問するのは初めてです。Androidアプリでこの問題が発生しました。カスタム ビュー クラス内にさまざまな描画メソッドを作成したいと考えています。3 つの異なる形状に対応する 3 つのボタンがあります。ボタンを押すと、その形状が描画されます。しかし、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" />`

助けてください!どうもありがとうございました!

4

4 に答える 4

2

あなたの質問を理解したら、イベントに基づいて独自に描画するカスタム ビュー (ボタン) が必要です。その場合は、ビューの描画に関する Android のガイドラインを尊重する必要があります。こちらをご覧ください。

あなたの場合の解決策の 1 つは、ビューの状態に関する何らかのフラグを設定し、描画の準備ができたときにそのフラグを使用することです。たとえば、これを行うことができます:

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 中にビュー関数を呼び出し、ビューの onDraw メソッドがその間呼び出されていないため、null キャンバスを使用しようとしています。さらに、他の人が指摘しているように、 onDraw メソッドの外で canvas オブジェクトを使用してはいけません。

お役に立てれば...

于 2013-07-11T15:26:51.690 に答える
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();
于 2013-07-11T14:52:45.377 に答える
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);
  }
}
于 2013-07-11T14:41:59.967 に答える