3

I want to draw a circle or any object on center of any device.but i am unable to get center of device in all device accurately.i am able to work on some device but on max its not drawing accurately.please help..thanks in advance.I am also posting my piece of code here as well

 package com.app.maxcircle;

import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;

public class CircleWithMaxRadiusActivity extends Activity {
    /** Called when the activity is first created. */

    float pixelCenterX, pixelCenterY;
    DrawCanvasCircle pcc;
    LinearLayout ll;
    private Canvas canvas;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Display display = getWindowManager().getDefaultDisplay();
        int width = display.getWidth();
        int height = display.getHeight();
        ll = (LinearLayout) findViewById(R.id.ll);
        float centerx = width / 2;
        float centery = height / 2;
        pixelCenterX = convertDpToPixel(centerx, this);
        pixelCenterY = convertDpToPixel(centery, this);
        System.out.println("px..." + pixelCenterX);
        System.out.println("py..." + pixelCenterY);

        pcc = new DrawCanvasCircle(this);
        Bitmap result = Bitmap.createBitmap(25, 25, Bitmap.Config.ARGB_8888);
        canvas = new Canvas(result);
        pcc.draw(canvas);
        pcc.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
                LayoutParams.FILL_PARENT));
        ll.addView(pcc);
    }

    public static float convertDpToPixel(float dp, Context context) {
        Resources resources = context.getResources();
        DisplayMetrics metrics = resources.getDisplayMetrics();
        float px = dp * (metrics.densityDpi / 160f);
        return px;
    }

    /**
     * This method converts device specific pixels to device independent pixels.
     * 
     * @param px
     *            A value in px (pixels) unit. Which we need to convert into db
     * @param context
     *            Context to get resources and device specific display metrics
     * @return A float value to represent db equivalent to px value
     */
    public static float convertPixelsToDp(float px, Context context) {
        Resources resources = context.getResources();
        DisplayMetrics metrics = resources.getDisplayMetrics();
        float dp = px / (metrics.densityDpi / 160f);
        return dp;

    }

    class DrawCanvasCircle extends View {
        public DrawCanvasCircle(Context mContext) {
            super(mContext);
        }

        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            Paint p = new Paint();
            p.setColor(Color.WHITE);
            DashPathEffect dashPath = new DashPathEffect(new float[] { 5, 5, 2,
                    2 }, (float) 1.0);

            p.setPathEffect(dashPath);
            p.setStyle(Style.STROKE);

            for (int i = 0; i < 25; i++) {
                canvas.drawCircle(pixelCenterX, pixelCenterY, pixelCenterY - 20
                        * i, p);
            }

            invalidate();
        }
    }

}
Manmohan Badaya
  • 2,326
  • 1
  • 22
  • 35
  • your `convertdptopx()` method do the Wrong thing. what you get from display.getHeight() is actually px. not dp – Aprian Aug 30 '12 at 06:34
  • and you also need to minus the notification bar or title bar size (if available), to get the exact height and width of your display screen. – Aprian Aug 30 '12 at 06:37
  • can you please help me to draw a circle exactly on center.if i put the value without changing in px also not drawing correctly.as i am not having any view on my layout – Manmohan Badaya Aug 30 '12 at 06:59
  • @MBMJ Please stop submitting one-character trivial edits. See the FAQ. – Craig Ringer Oct 09 '12 at 10:53

2 Answers2

0

Try this

public class TestSO extends Activity {
    /** Called when the activity is first created. */

    float pixelCenterX, pixelCenterY;
    DrawCanvasCircle pcc;
    LinearLayout ll;
    private Canvas canvas;
    private float centerX, centerY; 

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Display display = getWindowManager().getDefaultDisplay();
        int width = display.getWidth();
        int height = display.getHeight();
        ll = (LinearLayout) findViewById(R.id.ll);
        pixelCenterX = convertPixelsToDp(width, this) / 2;
        pixelCenterY = convertPixelsToDp(height, this) / 2;

        centerX = convertDpToPixel(pixelCenterX, this);
        centerY = convertDpToPixel(pixelCenterY, this);

        System.out.println("px..." + pixelCenterX);
        System.out.println("py..." + pixelCenterY);

        pcc = new DrawCanvasCircle(this);
        Bitmap result = Bitmap.createBitmap(25, 25, Bitmap.Config.ARGB_8888);
        canvas = new Canvas(result);
        pcc.draw(canvas);
        pcc.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
                LayoutParams.FILL_PARENT));
        ll.addView(pcc);
    }

    public static float convertDpToPixel(float dp, Context context) {
        Resources resources = context.getResources();
        DisplayMetrics metrics = resources.getDisplayMetrics();
        float px = dp * (metrics.densityDpi / 160f);
        return px;
    }

    /**
     * This method converts device specific pixels to device independent pixels.
     * 
     * @param px
     *            A value in px (pixels) unit. Which we need to convert into db
     * @param context
     *            Context to get resources and device specific display metrics
     * @return A float value to represent db equivalent to px value
     */
    public static float convertPixelsToDp(float px, Context context) {
        Resources resources = context.getResources();
        DisplayMetrics metrics = resources.getDisplayMetrics();
        float dp = px / (metrics.densityDpi / 160f);
        return dp;
    }

    class DrawCanvasCircle extends View {
        public DrawCanvasCircle(Context mContext) {
            super(mContext);
        }

        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            Paint p = new Paint();
            p.setColor(Color.WHITE);
            DashPathEffect dashPath = new DashPathEffect(new float[] { 5, 5, 2,
                    2 }, (float) 1.0);

            p.setPathEffect(dashPath);
            p.setStyle(Style.STROKE);

            for (int i = 0; i < 25; i++) {
                canvas.drawCircle(centerX, centerY, pixelCenterY - 20
                        * i, p);
            }

            invalidate();
        }
    }

}
Sieryuu
  • 1,510
  • 2
  • 16
  • 41
  • yes.but without converting it is not drawing correctly on each device as i have drwan on 320x480 with 160dpi desnity.but working on tab having 1200x780 – Manmohan Badaya Aug 30 '12 at 06:34
  • still not working as u can see from ur code [go to link](https://twitter.com/B_manmohan/status/241075220205686784/photo/1) – Manmohan Badaya Aug 30 '12 at 07:30
  • from width aspect it is in center but from height it is not as can see the circle approx touching from its height side having only 1 circle in bottom but 3 in top – Manmohan Badaya Aug 30 '12 at 07:39
0

ok here is the link for you to get the status bar and title bar size.

after that, you need to substract them with :

Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight() - statusHeight - titleHeight ;

ll = (LinearLayout) findViewById(R.id.ll);
float centerx = width / 2;
float centery = height / 2;

// you don't actually need to convert to Dp though, but if that is what you want then do it.
pixelCenterX = convertPixelToDp(centerx, this);
pixelCenterY = convertPixelToDp(centery, this);

good luck.

Community
  • 1
  • 1
Aprian
  • 1,718
  • 1
  • 14
  • 24
  • i am not having any other stuff in my layout and u can see what i am getting by applying this to my code..[go to link](https://twitter.com/B_manmohan/status/241075220205686784/photo/1) – Manmohan Badaya Aug 30 '12 at 07:37
  • nope, your layout do consist of title bar(CirclewithMaxRadius) and status bar(Time) – Aprian Aug 30 '12 at 07:39
  • yes...now when i removed both from view..now drawing correctly on each device ..thanks – Manmohan Badaya Aug 30 '12 at 07:56
  • yeah that's why i said, you need to calculate them if they are on your layout. please mark it as answer if my suggestion help =) – Aprian Aug 30 '12 at 07:57