Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
206 views
in Technique[技术] by (71.8m points)

Android Custom Layout - onDraw() never gets called

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));
        }
    }
}

Well there are almost NONE good and deep tutorials and hardly any piece of data on how to do custom layouts right, so i tried to figure out how its done, what i am trying to implement is a Layout that paints a green oval at the center of the screen, and i want every child of this layout to be layed out around the oval.

you can think of that oval as a poker table that i want the children of this layout to seat around it.

What currently happens by this code is that i get a white app scren with no oval, so i debugged it and saw that onDraw never gets called...

3 questions:

  1. why is onDraw not getting called?
  2. the sdk warns me that i shouldnt allocate new objects within onLayout method, so where should i calculate the RectF so it is ready for the onDraw call to come?
  3. does calling super.onDraw() would make all children paint themselves? or should i explicitly invoke their draw()?

If I got it all wrong and you guys can guide me in the right direction, or have any links to examples or tutorials related to this subject that would be helpful too!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

By default, onDraw() isn't called for ViewGroup objects. Instead, you can override dispatchDraw().

Alternatively, you can enable ViewGroup drawing by calling setWillNotDraw(false) in your TableView constructor.

EDIT:

For #2: - Initialize it in the constructor, then just call rect.set() in your onLayout() method.

For #3: - Yes, as far as I'm aware the super call will handle it, you shouldn't have to handle that unless you need to customize the way the children are drawn.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...