【问题标题】:how can i show a square image in a circle?如何在圆形中显示方形图像?
【发布时间】:2014-06-27 21:27:05
【问题描述】:

我正在尝试从我的应用程序的 iPhone 版本中模仿一些东西。我有一个方形图像,我想将它显示在一个带有白色边框的圆圈中。像这样

有什么办法可以做到吗?

【问题讨论】:

  • 那么它是 iPhone 应用程序还是 android 应用程序?我看到的是 android 标签,而不是 ios....
  • 我正在尝试在 android 中做到这一点。所以是的,它是一个 android 应用程序,屏幕截图是我的 iOS 应用程序。我正在尝试在 android 中做同样的事情
  • 看这个github.com/vinc3m1/RoundedImageView

标签: android android-layout android-shape


【解决方案1】:

您可以使用自定义的 Drawable 类来实现此效果或非常接近的效果,该类包含一个带有将图像渲染为纹理的 BitmapShader 的 Paint 对象。这是我正在使用的代码(略微改编自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);

【讨论】:

  • 谢谢,但我很困惑 png/jpeg 图像在哪里? item.mBitmap 部分?
  • 是的。您必须从 Bitmap 实例构建此可绘制对象(例如,从 BitmapDrawable 提取、从网络下载等)。建议:下载Romain的完整工程,真的很容易理解。然后用这个替换它的 StreamDrawable 类来看看效果。
【解决方案2】:

我会制作一个自定义视图,然后在画布上绘制你想要的东西——画边框,然后是白色圆圈,然后是图像。这是几个简单的画布调用。如果需要将图片裁剪成圆形区域,只需在绘制图片之前设置一个裁剪区域即可。

【讨论】:

    【解决方案3】:

    试试这个。

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

    【讨论】:

      猜你喜欢
      • 2021-03-17
      • 2019-11-08
      • 1970-01-01
      • 2021-08-22
      • 2020-06-05
      • 2019-05-25
      • 1970-01-01
      • 2014-04-29
      • 1970-01-01
      相关资源
      最近更新 更多