2012-10-24 26 views
35
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)); 
     } 
    } 
} 

Có hầu như KHÔNG có hướng dẫn tốt và sâu và hầu như không có bất kỳ dữ liệu nào về cách bố trí tùy chỉnh đúng, vì vậy tôi đã cố gắng tìm hiểu cách thực hiện Tôi đang cố gắng để thực hiện là một Layout vẽ một hình bầu dục màu xanh lá cây ở trung tâm của màn hình, và tôi muốn mọi đứa trẻ của bố trí này được bố trí xung quanh hình bầu dục.Bố cục tùy chỉnh Android - onDraw() không bao giờ được gọi là

bạn có thể nghĩ rằng hình bầu dục đó là một bàn chơi bài xì phé mà tôi muốn con cái của bố cục này ngồi quanh nó.

gì hiện đang xảy ra bởi mã này là tôi nhận được một scren ứng dụng màu trắng không có hình bầu dục, vì vậy tôi sửa lỗi nó và thấy rằng onDraw không bao giờ được gọi ...

3 câu hỏi sau:

  1. tại sao onDraw không được gọi?
  2. sdk cảnh báo tôi rằng tôi không nên cấp phát các đối tượng mới trong phương thức onLayout, vậy tôi nên tính RectF ở đâu để sẵn sàng cho cuộc gọi onDraw đến?
  3. gọi super.onDraw() sẽ khiến tất cả trẻ em tự vẽ? hoặc tôi nên gọi một cách rõ ràng vẽ của họ()?

Nếu tôi hiểu sai và bạn có thể hướng dẫn tôi đúng hướng hoặc có bất kỳ liên kết nào đến các ví dụ hoặc hướng dẫn liên quan đến chủ đề này cũng hữu ích!

Trả lời

119

Theo mặc định, onDraw() không được gọi cho các đối tượng ViewGroup. Thay vào đó, bạn có thể ghi đè dispatchDraw().

Hoặc, bạn có thể bật bản vẽ ViewGroup bằng cách gọi setWillNotDraw(false) trong hàm tạo TableView của mình.

Xem: Romain Guy's explanation

EDIT:

Đối # 2: - Khởi tạo nó trong các nhà xây dựng, sau đó chỉ cần gọi rect.set() trong phương pháp onLayout() của bạn.

Đối với # 3: - Có, theo như tôi biết cuộc gọi siêu sẽ xử lý, bạn không cần phải xử lý trừ khi bạn cần tùy chỉnh cách vẽ trẻ em.

+0

tuyệt vời đã hoạt động, cảm ơn !, còn các câu hỏi khác của tôi thì sao? –

+0

@kcoppock
Tên phương pháp được đề cập là ** not ** 'setWillNotDrawEnabled' nhưng chỉ đơn giản là' setWillNotDraw' (phương thức công khai của 'View'class). – lambruscoAcido

0

Nếu bạn muốn canvas được vẽ lại cuộc gọi không hợp lệ() và phương thức onDraw() sẽ được thực hiện lại

Các vấn đề liên quan