Android自定义布局 – onDraw()永远不会被调用

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=rl; float h=bt; 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)); } } } 

那么几乎没有什么好的和深入的教程,几乎没有关于如何做自定义布局的任何一块数据,所以我试图弄清楚它是如何完成的,我试图实现的是一个布局,在中心绘制一个绿色的椭圆形的屏幕上,我希望这个布局的每个孩子都摆在椭圆周围。

你可以把那个椭圆形看作是一张扑克牌桌,我希望这个布局的孩子能够围坐在桌子上。

目前这个代码发生了什么,我得到一个白色的应用程序scren没有椭圆形,所以我debugging它,看到onDraw永远不会被调用…

3个问题:

  1. 为什么onDraw没有被调用?
  2. sdk警告我,我不应该在onLayout方法中分配新的对象,所以我应该在哪里计算RectF,以便onDraw调用准备就绪?
  3. 调用super.onDraw()会使所有的孩子自己画吗? 或者我应该明确地调用他们的draw()?

如果我把它弄错了,你们可以指导我正确的方向,或者有任何与这个主题相关的例子或教程的链接,这也将是有益的!

默认情况下,不会为ViewGroup对象调用onDraw() 。 相反,你可以重写dispatchDraw()

或者,您可以通过在TableView构造函数中调用setWillNotDraw(false)来启用ViewGroup绘图。

见: 罗曼·盖伊的解释

编辑:

对于#2: – 在构造函数中初始化它,然后在你的onLayout()方法中调用rect.set()

对于#3: – 是的,据我所知,超级电话会处理它,你不应该处理,除非你需要定制的方式,孩子们的绘制。

如果你想要canvas被重新调用invalidate(),并且方法onDraw()将被重新执行