android 圆角图片实现(三)

前面已经提到了实现圆角的方法,现在是第三种,这种也是大家最熟悉的一种,稍后一看就明白了
还是和以前一样,上代码看效果。
1布局文件

<?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:orientation="vertical"
    android:padding="10dp">

    <com.example.apple.Custom.Matrix.RoundImagView
        android:id="@+id/mm1"
        android:layout_width="200dp"
        android:layout_height="200dp" />

    <com.example.apple.Custom.Matrix.RoundImagView
        android:id="@+id/mm2"
        android:layout_width="wrap_content"
        android:layout_height="150dp" />

    <com.example.apple.Custom.Matrix.RoundImagView
        android:id="@+id/mm3"
        android:layout_width="150dp"
        android:layout_height="wrap_content" />


</LinearLayout>

我们是自定义一个view,以前都是自定义drawable,这次会比以前更加简单,但是也会有一些细节问题,我们来一起见证一下

public class RoundImagView extends View{

    private int width, height, min;
    Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private Bitmap mbitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ns5);

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

    public RoundImagView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RoundImagView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int wmode = MeasureSpec.getMode(widthMeasureSpec);
        int hmode = MeasureSpec.getMode(heightMeasureSpec);
        int w = MeasureSpec.getSize(widthMeasureSpec);
        int h = MeasureSpec.getSize(heightMeasureSpec);

        if (wmode == MeasureSpec.EXACTLY && hmode == MeasureSpec.EXACTLY) {
            width = w;
            height = h;
        } else if (hmode == MeasureSpec.AT_MOST && wmode == MeasureSpec.AT_MOST) {
            width = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 100, getResources().getDisplayMetrics());
            height = width;
        } else {
            height = h;
            width = height;
        }
        min = Math.min(height - getPaddingTop() - getPaddingBottom(), width - getPaddingRight() - getPaddingLeft());
        setMeasuredDimension(width, height);

    }

    @Override
    protected void onDraw(Canvas canvas) {
        mbitmap = Bitmap.createScaledBitmap(mbitmap, width, height, false);
        Bitmap bitmap = createBitmap();
        canvas.drawBitmap(bitmap, 0, 0, null);
    }

    private Bitmap createBitmap() {
        Bitmap bitmap = Bitmap.createBitmap(getResources().getDisplayMetrics(), width, height, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        canvas.drawCircle(width / 2, height / 2, min / 2, paint);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(mbitmap, 0, 0, paint);
        return bitmap;
    }
}

activity里面啥也没做,核心就这一个类,一切都在这里面处理,先看下代码,onMeasure就没啥说的了,主要是根据布局里面的宽高mode处理view 的宽高问题,这个就自己看了。
在ondraw里面Bitmap.createScaledBitmap这个方法有点意思,看名称是缩放功能,为啥要这样呢,主要是图片太大的话,绘制到view上面只会出现一部分的画面,所以就根据图片的宽高和view的宽高进行缩放,这样绘制出来的画面才是全部的画面。进入这个createScaledBitmap方法,看看是如何缩放的。

 public static Bitmap createScaledBitmap(Bitmap src, int dstWidth, int dstHeight,
            boolean filter) {
        Matrix m;
        synchronized (Bitmap.class) {
            // small pool of just 1 matrix
            m = sScaleMatrix;
            sScaleMatrix = null;
        }

        if (m == null) {
            m = new Matrix();
        }

        final int width = src.getWidth();
        final int height = src.getHeight();
        final float sx = dstWidth  / (float)width;
        final float sy = dstHeight / (float)height;
        m.setScale(sx, sy);
        Bitmap b = Bitmap.createBitmap(src, 0, 0, width, height, m, filter);

        synchronized (Bitmap.class) {
            // do we need to check for null? why not just assign everytime?
            if (sScaleMatrix == null) {
                sScaleMatrix = m;
            }
        }

        return b;
    }

看代码通过宽高比,用矩阵来处理缩放尺寸,返回一个小尺寸的图片,但是这里会有个问题,后面再说。。
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));这个是处理俩个图片绘制怎么显示的工具。PorterDuff.Mode有16种模式,我们就用其中的一种PorterDuff.Mode.SRC_IN,详情可以查看官方文档
这里写图片描述

代码全部贴来了,看看女神效果了
这里写图片描述

看看圆角已经出来了,目的已经达到了,是不是就完了呢,且慢上面还遗留了一个问题,看图片也知道女神一会变胖了,一会儿瘦了,有点让我看着不舒服,追求完美的我,肯定不会让我的女神这样,这是一种侮辱,我一定要让观众看到她最漂亮的一面,那么往下看


    @Override
    protected void onDraw(Canvas canvas) {

        Bitmap bitmap = createBitmap();
        canvas.drawBitmap(bitmap, 0, 0, null);

    }
      private Bitmap createBitmap() {
        if (roundbitmap != null){
            return roundbitmap;
        }
        roundbitmap = Bitmap.createBitmap(getResources().getDisplayMetrics(), width, height, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(roundbitmap);
        canvas.drawCircle(width / 2, height / 2, min / 2, paint);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        Matrix matrix = new Matrix();
        int w = mbitmap.getWidth();
        int h = mbitmap.getHeight();
        final float sx = width * 1.0f / w;
        final float sy = height * 1.0f / h;
        float max = Math.max(sx, sy);
        matrix.setScale(max, max);
        canvas.drawBitmap(mbitmap, matrix, paint);
        return roundbitmap;
    }

这里用到了矩阵,不太明白的小伙伴可以看我以前的博客,或者查看官方文档,好了看图说话,流哈喇子吧

这里写图片描述

完美的女神终于回来了,女神就是女神呀,太漂亮了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值