如何在Android设备的中心绘制一个圆形

3

我希望在任何设备的中心绘制一个圆形或任何对象。但是我无法准确地在所有设备上获取设备的中心位置。我能够在一些设备上工作,但在某些设备上不准确。请帮忙解决。谢谢提前。我也在这里发布我的代码片段。

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

}

你的 convertdptopx() 方法做错了事。你从 display.getHeight() 得到的实际上是像素 (px) ,而不是设备独立像素 (dp)。 - Aprian
你还需要减去通知栏或标题栏的大小(如果有的话),以获取您显示屏的确切高度和宽度。 - Aprian
你能帮我在中心画一个圆吗?即使我不改变px的值,它也无法正确绘制。因为我的布局上没有任何视图。 - Manmohan Badaya
@MBMJ请停止提交单个字符的琐碎编辑。请查看常见问题解答。 - Craig Ringer
2个回答

0

试试这个

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

}

是的,但是如果不转换,它在每个设备上都无法正确绘制,因为我已经使用160dpi密度在320x480上绘制了它,但在拥有1200x780分辨率的平板电脑上可以正常工作。 - Manmohan Badaya
仍然无法正常工作,如您所见从您的代码[转至链接]。 - Manmohan Badaya
从宽度方面来看,它是在中心位置的,但从高度方面来看,可以看到圆形近似于从其高度侧面接触,底部只有1个圆,而顶部有3个圆。 - Manmohan Badaya

0

好的,这里是链接,让你获取状态栏和标题栏的大小。

之后,你需要用它们相减:

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

祝你好运。


我的布局中没有其他的东西,你可以通过将这个应用到我的代码中来看到我得到了什么。点击链接 - Manmohan Badaya
不好意思,你的布局确实包括标题栏(最大半径为圆形)和状态栏(时间)。 - Aprian
是的...现在当我从视图中移除它们时,每个设备上都可以正确绘制了..谢谢。 - Manmohan Badaya
是的,这就是为什么我说,如果它们在你的布局上,你需要计算它们。如果我的建议有帮助,请将其标记为答案 =) - Aprian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接