如何在圆圈中显示方形图像?

时间:2014-05-10 02:26:15

标签: android android-layout android-shape

我试图模仿我的应用程序的iPhone版本中的某些内容。我有一个方形图像,我想把它显示在一个圆圈周围有一个白色边框。像这样

enter image description here

我有办法做到这一点吗?

3 个答案:

答案 0 :(得分:0)

您可以使用自定义Drawable类来实现此效果或非常接近它的效果,该类包含具有BitmapShader的Paint对象,该BitmapShader将图像呈现为纹理。这是我使用的代码(稍微改编自Romain's Guy post,它使用相同的技术绘制带圆角的图像)。

class CircularDrawable extends Drawable
{
    private float mCircleRadius;
    private final RectF mBackgroundRect = new RectF();
    private final Paint mBackgroundPaint;
    private final BitmapShader mBitmapShader;
    private final Paint mPaint;
    private final int mMargin;

    CircularDrawable(Bitmap bitmap, int margin, int backgroundColor)
    {
        mBitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);

        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setShader(mBitmapShader);

        mMargin = margin;
        mBackgroundPaint = new Paint();
        mBackgroundPaint.setColor(backgroundColor);
    }

    @Override
    protected void onBoundsChange(Rect bounds)
    {
        super.onBoundsChange(bounds);
        mBackgroundRect.set(bounds);
        mCircleRadius = Math.min(bounds.width() / 2 - mMargin, bounds.height() / 2 - mMargin);
    }

    @Override
    public void draw(Canvas canvas)
    {
        canvas.drawRect(mBackgroundRect, mBackgroundPaint);
        canvas.drawCircle(mBackgroundRect.width() / 2, mBackgroundRect.height() / 2, mCircleRadius, mPaint);
    }

    @Override
    public int getOpacity()
    {
        return PixelFormat.TRANSLUCENT;
    }

    @Override
    public void setAlpha(int alpha)
    {
        mPaint.setAlpha(alpha);
        mBackgroundPaint.setAlpha(alpha);
    }

    @Override
    public void setColorFilter(ColorFilter cf)
    {
        mPaint.setColorFilter(cf);
        mBackgroundPaint.setColorFilter(cf);
    }       
}

拥有您想要绘制的位图,只需使用

从中构建一个CircularDrawable
new CircularDrawable(bitmap, margin, Color.WHITE);

答案 1 :(得分:0)

试试这个。

public class CircularImageView extends ImageView {
private int borderWidth;
private int viewWidth;
private int viewHeight;
private Bitmap image;
private Paint paint;
private Paint paintBorder;
private BitmapShader shader;

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)) {
        setBorderWidth(attributes.getColor(
                R.styleable.CircularImageView_border_width, 4));
        setBorderColor(attributes.getInt(
                R.styleable.CircularImageView_border_color, Color.WHITE));
    }

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

public void setBorderWidth(int borderWidth) {
    this.borderWidth = borderWidth;
    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);
}

@SuppressLint("DrawAllocation")
@Override
public void onDraw(Canvas canvas) {
    // load the bitmap
    BitmapDrawable bitmapDrawable = (BitmapDrawable) this.getDrawable();
    if (bitmapDrawable != null)
        image = bitmapDrawable.getBitmap();

    // init shader
    if (image != null) {
        shader = new BitmapShader(Bitmap.createScaledBitmap(image,
                canvas.getWidth(), canvas.getHeight(), false),
                Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        paint.setShader(shader);
        int circleCenter = viewWidth / 2;

        // 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
        canvas.drawCircle(circleCenter + borderWidth, circleCenter
                + borderWidth, circleCenter + borderWidth - 4.0f,
                paintBorder);
        canvas.drawCircle(circleCenter + borderWidth, circleCenter
                + borderWidth, circleCenter - 4.0f, paint);
    }
}

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

    viewWidth = width - (borderWidth * 2);
    viewHeight = height - (borderWidth * 2);

    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) {
        // We were told how big to be
        result = specSize;
    } else {
        // Measure the text
        result = viewWidth;
    }

    return result;
}

private int measureHeight(int measureSpecHeight, int measureSpecWidth) {
    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 {
        // Measure the text (beware: ascent is a negative number)
        result = viewHeight;
    }

    return (result + 2);
}
}

答案 2 :(得分:-1)

我会制作一个自定义视图,只需绘制你想要的画布 - 绘制边框,然后是白色圆圈,然后是图像。这是一些简单的画布调用。如果您需要将图像剪切为圆形区域,只需在进行图像绘制之前设置剪裁区域。