最近一段时间学了很多关于圆角矩形或者圆角图片制作的文章,写的都很好,但是每次一学完都会做,但是过段时间又不记得该怎么写代码了,反思了一下,是自己只是在看,并没有真正的消化,所以还不算自己的东西,于是今天又把大神的代码又看了看,自己总结,自己再写一遍,算是明白了吧,也想写个文章记录一下,方便下次寻找,也可以分享出来。
Xfermode是android画笔Paint可以设置的一种画笔属性,具体就是可以把两张图片进行组合,根据设置的形式,可以组合多种形式,具体大家看图:
这里用的就是SrcIn模式,大致思路就是先绘制一个圆或者圆角矩形,然后再绘制我们的图片,然后根据上面的SrcIn模式,最终就绘制出了圆形图片或者圆角矩形。android里面把先绘制的图片视为Src,后绘制的是Dst。
具体代码如下,里面说的很详细了。
package com.fanxl.roundview; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.PorterDuff.Mode; import android.graphics.PorterDuffXfermode; import android.graphics.RectF; import android.util.AttributeSet; import android.view.View; public class RoundView extends View { private Bitmap src; private Bitmap out; private int width; private int height; private int type; private static final int TYPE_CIRCLE = 0; private static final int TYPE_ROUND = 1; public RoundView(Context context) { this(context, null); } public RoundView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public RoundView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initView(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //自己计算控件的宽高 int widthSize = MeasureSpec.getSize(widthMeasureSpec); int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); if (widthMode == MeasureSpec.EXACTLY) { width = widthSize; } else { int imgWidth = src.getWidth() + getPaddingLeft() + getPaddingRight(); if (widthMode == MeasureSpec.AT_MOST) { width = Math.min(widthSize, imgWidth); } else { width = imgWidth; } } if (heightMode == MeasureSpec.EXACTLY) { height = heightSize; } else { int imgHeight = src.getHeight() + getPaddingTop() + getPaddingBottom(); if (heightMode == MeasureSpec.AT_MOST) { height = Math.min(heightSize, imgHeight); } else { height = imgHeight; } } //根据要绘制的类型设置最终自定义控件的宽高 switch (type) { case TYPE_CIRCLE: int min = Math.min(width, height); setMeasuredDimension(min, min); break; case TYPE_ROUND: setMeasuredDimension(width, height); break; } } @SuppressLint("NewApi") private void initView() { // 禁止硬件加速,硬件加速会有一些问题,这里禁用掉 setLayerType(LAYER_TYPE_SOFTWARE, null); src = BitmapFactory.decodeResource(getResources(), R.drawable.dd); //设置类型,是圆角图片还是圆角矩形 type = TYPE_CIRCLE; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); xmodeImage(); //把画好画的画布放到自定义的画板上面 canvas.drawBitmap(out, 0, 0, null); } private void xmodeImage() { //根据原始的图片创建一个画布 out = Bitmap.createBitmap(width, height, Config.ARGB_8888); //创建一个画板,在画布的基础上 Canvas canvas = new Canvas(out); //创建一个画笔 Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); switch (type) { case TYPE_ROUND: //开始在有画板的画布上用画笔作画了,这里画了一个圆角矩形 canvas.drawRoundRect(new RectF(0, 0, width, height), 60, 60, paint); break; case TYPE_CIRCLE: //画圆,取宽高的最小值作为圆的直径 int min = Math.min(width, height); //开始画圆 canvas.drawCircle(min/2, min/2, min/2, paint); break; } //设置Xfermode画笔模式为SRC_IN paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); //然后有画了一个图片,最终实现两个图像的叠加 canvas.drawBitmap(src, 0, 0, paint); } }
原文地址:http://blog.csdn.net/fanxl10/article/details/45040043