如何在android中心绘制一个圆圈

时间:2014-12-16 18:30:31

标签: android android-layout android-fragments android-linearlayout android-canvas

我希望圆形图像位于中心 如何将它放在设备的中心?

我不想使用相对布局。我已经准备好了,但它需要一个硬编码值的圆圈;因此。它不适用于所有设备。 我试图通过LinearLayout实现它(使用android:layout_weight属性) 我试过android:layout_gravity="center",android:gravity="center" 但是圆圈仍然不会到达中心。 我已附上屏幕以供参考

enter image description here

我希望圈子位于父中心

我的xml是:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res/com.example.dd"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="center"
    android:orientation="vertical" >

    <LinearLayout
        android:id="@+id/LinearLayout02"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
       android:layout_gravity="center"  
        android:orientation="horizontal" >

        <Button
            android:id="@+id/Button04"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="left1" >
        </Button>

        <com.example.dd.CircularImageView
            android:id="@+id/round"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:src="@drawable/buttonarea"
            app:border="true"
            app:border_color="#323232"
            app:border_width="55dp"
            app:shadow="true" />

        <Button
            android:id="@+id/Button08"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="right" >
        </Button>
    </LinearLayout>

</LinearLayout>

我的通函是:

     public class CircularImageView extends ImageView {
        private int borderWidth;
        private int canvasSize;
        private Bitmap image;
        private Paint paint;
        private Paint paintBorder;

        public CircularImageView(final Context context) {
            this(context, null);
        }

        public CircularImageView(Context context, AttributeSet attrs) {
            this(context, attrs, R.attr.circularImageViewStyle);
        }

        public CircularImageView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);

            // init paint
            paint = new Paint();
            paint.setAntiAlias(true);

            paintBorder = new Paint();
            paintBorder.setAntiAlias(true);

            // load the styled attributes and set their properties
            TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.CircularImageView, defStyle, 0);

            if(attributes.getBoolean(R.styleable.CircularImageView_border, true)) {
                int defaultBorderSize = (int) (4 * getContext().getResources().getDisplayMetrics().density + 0.5f);
                setBorderWidth(attributes.getDimensionPixelOffset(R.styleable.CircularImageView_border_width, defaultBorderSize));
                setBorderColor(attributes.getColor(R.styleable.CircularImageView_border_color, Color.WHITE));
            }

            if(attributes.getBoolean(R.styleable.CircularImageView_shadow, false))
                addShadow();
        }

        public void setBorderWidth(int borderWidth) {
            Log.d("TAG","::::::::::::borderWidth"+borderWidth);
            this.borderWidth = borderWidth;
            this.requestLayout();
            this.invalidate();
        }

        public void setBorderColor(int borderColor) {
            if (paintBorder != null)
                paintBorder.setColor(borderColor);
            this.invalidate();
        }

    public void addShadow() {
        setLayerType(LAYER_TYPE_SOFTWARE, paintBorder);
        paintBorder.setShadowLayer(4.0f, 0.0f, 2.0f, Color.BLACK);
    }

    @Override
    public void onDraw(Canvas canvas) {
        // load the bitmap
        image = drawableToBitmap(getDrawable());

        // init shader
        if (image != null) {

            canvasSize = canvas.getWidth();
            Log.d("TAG","::::::::::::canvasSize"+canvasSize);
            if(canvas.getHeight()<canvasSize)
                canvasSize = canvas.getHeight();

            BitmapShader shader = new BitmapShader(Bitmap.createScaledBitmap(image, canvasSize, canvasSize, false), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
            paint.setShader(shader);

            // circleCenter is the x or y of the view's center
            // radius is the radius in pixels of the cirle to be drawn
            // paint contains the shader that will texture the shape
            int circleCenter = (canvasSize - (borderWidth * 2)) / 2;
            canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, ((canvasSize - (borderWidth * 2)) / 2) + borderWidth - 4.0f, paintBorder);
            canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, ((canvasSize - (borderWidth * 2)) / 2) - 4.0f, paint);
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = measureWidth(widthMeasureSpec);
        int height = measureHeight(heightMeasureSpec);
        setMeasuredDimension(width, height);
    }

    private int measureWidth(int measureSpec) {
        int result = 0;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);

        if (specMode == MeasureSpec.EXACTLY) {
            // The parent has determined an exact size for the child.
            result = specSize;
        } else if (specMode == MeasureSpec.AT_MOST) {
            // The child can be as large as it wants up to the specified size.
            result = specSize;
        } else {
            // The parent has not imposed any constraint on the child.
            result = canvasSize;
        }

        return result;
    }

    private int measureHeight(int measureSpecHeight) {
        int result = 0;
        int specMode = MeasureSpec.getMode(measureSpecHeight);
        int specSize = MeasureSpec.getSize(measureSpecHeight);

        if (specMode == MeasureSpec.EXACTLY) {
            // We were told how big to be
            result = specSize;
        } else if (specMode == MeasureSpec.AT_MOST) {
            // The child can be as large as it wants up to the specified size.
            result = specSize;
        } else {
            // Measure the text (beware: ascent is a negative number)
            result = canvasSize;
        }

        return (result + 2);
    }


    public Bitmap drawableToBitmap(Drawable drawable) {
                if (drawable == null) {
                    return null;
                } else if (drawable instanceof BitmapDrawable) {
                    return ((BitmapDrawable) drawable).getBitmap();
                }

                Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
                        drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
                Canvas canvas = new Canvas(bitmap);
                drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
                drawable.draw(canvas);

                return bitmap;
            }

我的attrs.xml包含值:

<?xml version="1.0" encoding="utf-8"?>

    <resources>

        <declare-styleable name="CircularImageView">
            <attr name="border" format="boolean"></attr>
            <attr name="border_width" format="dimension"></attr>
            <attr name="border_color" format="color"></attr>
            <attr name="shadow" format="boolean"></attr>
        </declare-styleable>

        <declare-styleable name="Theme">
            <attr name="circularImageViewStyle" format="reference"></attr>
        </declare-styleable>

    </resources>

4 个答案:

答案 0 :(得分:2)

使用一些假布局并将可见性设置为不可见。这应该可以解决问题。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/com.example.dd"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:orientation="vertical" >

<LinearLayout
    android:id="@+id/LinearLayout02"
    android:layout_width="fill_parent"
    android:layout_height="match_parent"
    android:layout_gravity="center"
    android:orientation="horizontal" >

    <Button
        android:id="@+id/Button04"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="left1" >
    </Button>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:orientation="vertical" >

        <Button
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:orientation="vertical"
            android:text="dummy"
            android:visibility="invisible" >
        </Button>

        <Button
            android:id="@+id/round"
            android:layout_width="fill_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@android:drawable/star_on"
            app:shadow="true" />

        <Button
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:orientation="vertical"
            android:text="dummy"
            android:visibility="invisible" >
        </Button>
    </LinearLayout>

    <Button
        android:id="@+id/Button08"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="right" >
    </Button>
 </LinearLayout>

</LinearLayout>

答案 1 :(得分:1)

试试这个

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/com.example.dd"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:orientation="vertical" >

<LinearLayout
    android:id="@+id/LinearLayout02"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
   android:layout_gravity="center"  
    android:orientation="horizontal" >

    <Button
        android:id="@+id/Button04"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="left1" >
    </Button>

    <com.example.dd.CircularImageView
        android:id="@+id/round"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:src="@drawable/buttonarea"
        android:layout_gravity="center"
        app:border="true"
        app:border_color="#323232"
        app:border_width="55dp"
        app:shadow="true" />

    <Button
        android:id="@+id/Button08"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="right" >
    </Button>
</LinearLayout>

答案 2 :(得分:0)

一种方法是将LinearLayout高度设置为match_parent,然后将圈子上的layout_gravity设置为center_vertical

编辑:刚刚测试过,这对我有用:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:layout_gravity="center"
              android:orientation="vertical">

    <LinearLayout
        android:id="@+id/LinearLayout02"
        android:layout_width="fill_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"
        android:orientation="horizontal">

        <Button
            android:id="@+id/Button04"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="left1">
        </Button>

        <com.example.dd.CircularImageView
            android:id="@+id/round"
            android:layout_width="fill_parent"
            android:layout_gravity="center_vertical"
            android:layout_height="wrap_content"
            android:background="@android:color/black"
            android:layout_weight="1"/>

        <Button
            android:id="@+id/Button08"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="right">
        </Button>
    </LinearLayout>

</LinearLayout>

忽略背景颜色和缺少app:属性,一般的想法保持不变。

答案 3 :(得分:0)

试试这个:

<com.example.dd.CircularImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/myCircularImageView"
    android:src="@drawable/buttonarea"
    android:layout_centerVertical="true"
    android:layout_centerHorizontal="true"/>