android 圆角图片实现(三)

来源:互联网 发布:软件外包公司资质 编辑:程序博客网 时间:2024/06/01 22:03

前面已经提到了实现圆角的方法,现在是第三种,这种也是大家最熟悉的一种,稍后一看就明白了
还是和以前一样,上代码看效果。
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;    }

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

这里写图片描述

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

原创粉丝点击