0

I'm trying to draw a circumference that would represent the battery life in a activity.

My parent layout is a relative layout.

This is the inner class that draws the view:

public class DrawView extends View {
    Paint mPaint = new Paint();

    public DrawView(Context context) {
        super(context);
    }

    @Override
    public void onDraw(Canvas canvas) {
        Paint mPaint = new Paint(Paint.FILTER_BITMAP_FLAG |
                Paint.DITHER_FLAG |
                Paint.ANTI_ALIAS_FLAG);
        mPaint.setDither(true);
        mPaint.setColor(Color.GRAY);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(1);

        int size = 200;
        int radius = 190;
        int delta = size - radius;
        int arcSize = (size - (delta / 2)) * 2;
        int percent = 42;

        //Thin circle
        canvas.drawCircle(size, size, radius, mPaint);

        //Arc
        mPaint.setColor(getResources().getColor(R.color.eCarBlue));
        mPaint.setStrokeWidth(15);
        RectF box = new RectF(delta,delta,arcSize,arcSize);
        float sweep = 360 * percent * 0.01f;
        canvas.drawArc(box, 0, sweep, false, mPaint);
    }

}

And in onCreate() I start the view this way:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    ...

    ViewGroup myLayout = (ViewGroup) findViewById(R.id.mainlayout);
    drawing = new DrawView(this);
    myLayout.addView(drawing);
}

But I need to locate this view in the layout, especifically in the center of it. To achieve this, I have modified onCreate()'s code this way:

ViewGroup myLayout = (ViewGroup) findViewById(R.id.mainlayout);
drawing = new DrawView(this);
RelativeLayout.LayoutParams layoutParams= new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
            RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
drawing.setLayoutParams(layoutParams);
myLayout.addView(drawing);

But it isn't having effect on the view. What would be then the correct way to define the params for the view?

Amarjit
  • 4,327
  • 2
  • 34
  • 51
masmic
  • 3,526
  • 11
  • 52
  • 105

1 Answers1

1

You're adding DrawView with LayoutParams.WRAP_CONTENT, which means the system needs to ask the view its width and height. You should implement onMeasure() for that. But I've never done that so don't know the details.

Another way is to just use LayoutParams.MATCH_PARENT and draw your stuff in onDraw() centered yourself. In this case you will need to know the width and height of the canvas in order to calculate the coordinates of your draw calls. Calling getWidth() in onDraw() does not give you the expected results. You need to override onSizeChanged() and record the new width and height, like this:

private int canvasWidth;
private int canvasHeight;

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    canvasWidth = w;
    canvasHeight = h;
}

Then in onDraw() you can use canvasWidth and canvasHeight because the onSizeChanged() has already happened.

Rob Meeuwisse
  • 2,847
  • 1
  • 17
  • 21
  • Well, I have done something like this few minutes before. I have realized that I can center the view in onDraw and for that I have used getWidth() and getHeight() and has centered the view. Now I have changed that with you method using onSizeChanged, maybe is better approach but the result is the same. Anyway, your answer to the question is right. – masmic Dec 18 '14 at 12:03
  • Just one more thing... In an old device, the view has the desired size, but in a Galaxy S5 is smaller than in the old device. i think this has something to do with the `radius` value. How can I set the radius value to be the same in all screen densities? – masmic Dec 18 '14 at 12:05
  • 1
    The radius is in pixels which would look different on screens with different pixel densities. Android has the concept of a device independent pixel (dip) which is equivalent to a physical pixel on a 160 pixels per inch screen. So 16 dips would be 0.1 inch on any screen. I guess that is what you need. So translate from dips to pixels. See [this](http://stackoverflow.com/questions/4605527/converting-pixels-to-dp) SO question for details how. – Rob Meeuwisse Dec 19 '14 at 12:23