自定义圆形图像视图

时间:2014-07-31 06:41:21

标签: android imageview

我正在尝试创建圆形图像视图。搜索谷歌后,我尝试了一些东西,但它不起作用。

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;

class WheelItemView extends ImageView {

    private int _index;
    private float _x;
    private float _y;
    private int _width;
    private int _height;
    private boolean _drawn;
    private float _currentAngle;

    private Paint paint;
    private Paint paintBorder;
    private int borderWidth;

    private boolean _hasRotation = false;
    private float _dx=0;
    private float _dy=0;
    private Bitmap image;
    private int canvasSize;


    public WheelItemView(Context context) {
        this(context, null);
    }   

    public WheelItemView(Context context, AttributeSet attrs) {
        this(context, attrs, in.eaft.byoo.R.attr.circularImageViewStyle);
    //  this(context, attrs, 0);
    }

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

        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, in.eaft.byoo.R.styleable.CircularImageView, defStyle, 0);

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

        if(attributes.getBoolean(in.eaft.byoo.R.styleable.CircularImageView_shadow, true))
            addShadow();

    }

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

    }

    private void setBorderColor(int color) {
        if(paintBorder != null)
            paintBorder.setColor(color);

        this.invalidate();


    }

    private void setBorderWidth(int borderWidth) {
        this.borderWidth = borderWidth;
        this.requestLayout();
        this.invalidate();

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        /*_width= measureWidth(widthMeasureSpec);
        _height = measureHeight(heightMeasureSpec);*/
        setMeasuredDimension(_width, _height);
    }

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

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

    @Override
    public void setImageBitmap(Bitmap src)
    {   
        _width = src.getWidth();
        _height = src.getHeight();

        if(_hasRotation) {
            calculateDistance();
        }

        super.setImageBitmap(src);
    }

    @Override
    protected void onDraw(Canvas canvas)
    {
        //if(_hasRotation) {
            /*Drawable d = getDrawable();
            if(d!=null && d instanceof BitmapDrawable && ((BitmapDrawable)d).getBitmap()!=null) {
                Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
                canvas.save();
                canvas.translate(_dx, _dy);
                canvas.rotate(_currentAngle+90, _width/2f, _height/2f);
                //              canvas.drawText(text, 0, 0, p);
                canvas.drawBitmap(((BitmapDrawable)d).getBitmap(),0, 0, p);
                canvas.restore();
                return;
            }*/


            System.out.println("get drawable is null : " + (getDrawable() == null));
            image = drawableToBitmap(getDrawable());

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

                canvasSize = canvas.getWidth();
                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.save();
            //  canvas.translate(_dx, _dy);
                canvas.rotate(_currentAngle+90, _width/2f, _height/2f);


                canvas.drawCircle(_width-_dx, _height-_dy/2, 
                        borderWidth * 10, paintBorder);
                canvas.drawCircle(_width-_dx, _height-_dy/2, 
                        borderWidth * 10, paint);
                /*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);*/
                canvas.restore();
    //      }
        }

        super.onDraw(canvas);
    }

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

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

        return bitmap;
    }

    private void calculateDistance() 
    {
        _dx = (float) ((Math.sqrt(_width*_width + _height*_height)-_width)/2.0f);
        _dy = (float) ((Math.sqrt(_width*_width + _height*_height)-_height)/2.0f);
    }

    public void setIndex(int index) 
    {
        this._index = index;
    }

    public int getIndex() 
    {
        return _index;
    }

    public void setCurrentAngle(float currentAngle) 
    {
        this._currentAngle = currentAngle;
    }

    public float getCurrentAngle() 
    {
        return _currentAngle;
    }

    public void setAxisX(float x) 
    {
        this._x = x;
    }

    public float getAxisX() 
    {
        return _x;
    }

    public void setAxisY(float y) 
    {
        this._y = y;
    }

    public float getAxisY() 
    {
        return _y;
    }

    public void setDrawn(boolean drawn) 
    {
        this._drawn = drawn;
    }

    public boolean isDrawn() 
    {
        return _drawn;
    }

    public void setItemWidth(int _width) 
    {
        this._width = _width;
    }

    public float getItemWidth() 
    {
        return _width;
    }

    public void setItemHeight(int _height) 
    {
        this._height = _height;
    }

    public float getItemHeight() 
    {
        return _height;
    }

    public int getDistanceX() 
    {
        return (int)_dx;
    }

    public int getDistanceY() 
    {
        return (int)_dy;
    }

    public void setRotatedItem(Boolean flag) 
    {
        _hasRotation = flag;
        if(_hasRotation && (_dx==0 || _dy ==0)) {
            calculateDistance();
        }

        if(!_hasRotation) {
            _dx = _dy = 0;
        }
    }


}

我的图像不是圆形的。圆形的一部分显示在方形图像的后面。 谁能告诉我我做了什么错误?

1 个答案:

答案 0 :(得分:0)

我想你要求这个

jst在res&gt; drawable

中创建一个形状
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval" >
<solid android:color="#a7a7a7" />
<stroke android:width="1dp" android:color="#818181" />
</shape>

并在ur imageview中使用此形状