前面已经提到了实现圆角的方法,现在是第三种,这种也是大家最熟悉的一种,稍后一看就明白了
还是和以前一样,上代码看效果。
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;
}
这里用到了矩阵,不太明白的小伙伴可以看我以前的博客,或者查看官方文档,好了看图说话,流哈喇子吧
完美的女神终于回来了,女神就是女神呀,太漂亮了。