android_nwb
android_nwb

Reputation: 3

Simple Android UI - Circles (Child views) in RelativeLayout

I am very new to Android and I am having problems figuring out how to layout views within a RelativeLayout programmatically. What I want to do is create 4 circles (child views) with a certain radius (say 50px) in the center of the RelativeLayout container, so it would look like I have an imaginary square in the center of the RelativeLayout and each vertex is the center for one of the circles.

I am able to draw the circle in the view; that is simple enough :)

class CircleView extends View {
    ...
    protected void onDraw(Canvas canvas) {
        // draw circle on canvas
    }
}

What I cannot figure out is how to layout the views. It seems to draw them on top of each other, even though I am setting LayoutParams and an Id for each of the child views.

class Circles extends RelativeLayout {
    public Circles(Context c) {
        super(c);
        addChildViews();
    }

    ...
    private void addChildViews() {
        final Context c = getContext();
        final CircleView v0 = new CircleView(c);
        v0.setId(0);

        final RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        params.addRule(RelativeLayout.LEFT_OF, 1);
        params.addRule(RelativeLayout.ABOVE, 2);
        v0.setLayoutParams(params);
        addView(v0);
        ....
        // and so on, with relative layout params for other 3 views
    }
}

Can somebody put me on the right track please? I also don't know if I am not calling addChildViews at the right time in the drawing cycle, and if this is what is leading to them being drawn on top of each other. Many thanks for any help.

Upvotes: 0

Views: 1804

Answers (1)

Joe
Joe

Reputation: 4811

Two things

1)The default action of a View is to fill its parent, so by applying (LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT) as your LayoutParams, you're creating four views with heights and widths the size of your parent layout (presumably the screen), so you'd only see one as the others would be positioned offscreen.

To fix this, either set the size you want the circles to be as your LayoutParms,

float dpi = getResources().getDisplayMetrics().density;
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams((int)(50.0f * dpi), (int)(50.0f * dpi));

or you could override the onMeasure(int x, int y) method in your Circle View like so

        @Override
        public void onMeasure(int x, int y) {
            float dpi = getResources().getDisplayMetrics().density;
            setMeasuredDimension((int)(50.0f * dpi), (int)(50.0f * dpi));
            }

2) Don't set your View id to 0...I can't remember if it's system reserved or what, but it doesn't play nice.

Additionally, if you want all the circles centered in your Circles, you'll want to set its gravity to center like so.

    public class Circles extends RelativeLayout {
        public Circles (Context ctx) {
            super(ctx);
            this.setGravity(Gravity.CENTER);
            addViewChildren();
        }

This will center all of the Circles children, giving you the desired result.

Upvotes: 0

Related Questions