54
public class MainActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        TableView tv = new TableView(this);
        tv.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT));
        setContentView(tv);      
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
}

public class TableView extends ViewGroup {
    private Paint oval;
    private RectF rect;

    public TableView(Context context) {
        super(context);
        oval= new Paint(Paint.ANTI_ALIAS_FLAG);
        oval.setColor(Color.GREEN);
    }


    public void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawOval(rect , oval);
    }
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int wspec = MeasureSpec.makeMeasureSpec(
                getMeasuredWidth(), MeasureSpec.EXACTLY);
        int hspec = MeasureSpec.makeMeasureSpec(
                getMeasuredHeight(), MeasureSpec.EXACTLY);
        for(int i=0; i<getChildCount(); i++){
            View v = getChildAt(i);
            v.measure(wspec, hspec);
        }
    }


    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        float w=r-l;
        float h=b-t;
        rect=new RectF(w/8,h/8,7*w/8,7*h/8);
        float theta = (float) (2 * Math.PI / getChildCount());
        for(int i=0; i< getChildCount(); i++) {
            View v = getChildAt(i);
            w = (rect.right-rect.left)/2;
            h = (rect.bottom-rect.top)/2;
            float half = Math.max(w, h)/2;
            float centerX = rect.centerX()+w*FloatMath.cos(theta);
            float centerY = rect.centerY()+h*FloatMath.sin(theta);
            v.layout((int)(centerX-half),(int)(centerY-half),(int)(centerX+half),(int)(centerY+half));
        }
    }
}

よくて深いチュートリアルはほとんどなく、カスタムレイアウトを正しく行う方法に関するデータはほとんどないので、その方法を理解しようとしました。実装しようとしているのは、中央に緑色の楕円を描くレイアウトです。画面の、そして私はこのレイアウトのすべての子が楕円形の周りに配置されることを望みます。

その楕円形は、このレイアウトの子供たちにその周りに座ってもらいたいポーカーテーブルと考えることができます。

このコードで現在起こっていることは、楕円形のない白いアプリ画面を取得することです。そのため、デバッグして、onDrawが呼び出されないことを確認しました...

3つの質問:

  1. onDrawが呼び出されないのはなぜですか?
  2. SDKは、onLayoutメソッド内に新しいオブジェクトを割り当てるべきではないことを警告します。したがって、onDraw呼び出しの準備ができるように、RectFをどこで計算する必要がありますか?
  3. super.onDraw()を呼び出すと、すべての子が自分でペイントしますか?または、明示的にdraw()を呼び出す必要がありますか?

私がそれをすべて間違っていて、あなたたちが私を正しい方向に導くことができるか、この主題に関連する例やチュートリアルへのリンクがあれば、それも役に立ちます!

4

2 に答える 2

163

デフォルトでは、オブジェクトに対してonDraw()は呼び出されません。ViewGroup代わりに、をオーバーライドできますdispatchDraw()

または、コンストラクターViewGroupを呼び出して描画をsetWillNotDraw(false)有効にすることもできます。TableView

編集:

#2の場合:-コンストラクターで初期化しrect.set()onLayout()メソッドを呼び出すだけです。

#3の場合:-はい、スーパーコールがそれを処理することを私が知っている限り、子の描画方法をカスタマイズする必要がない限り、それを処理する必要はありません。

于 2012-10-24T19:32:57.223 に答える
-3

キャンバスを再描画する場合は、invalidate()を呼び出すと、onDraw()メソッドが再実行されます。

于 2014-02-13T15:44:33.543 に答える