一個簡單的自定義CircleDrawable,實現圓形頭像效果
Github上有一個star5000+的 CircleImageView ,代碼設計得十分簡潔流暢,其實通過自定義一個Drawable也完全可以實現這個效果。(ps:其實是今天在看源碼的時候,在Setting模塊看到了一個類似的CircleFramedDrawable~,自己幾乎沒有修改就能實現圓形圖片的效果)。
因為代碼十分簡單,所以一些簡單分析就直接寫在注釋里了。這里只說一下實現思路:通過為畫筆設置PorterDuff.Mode,來讓新建的圓形圖層與原Bitmap只顯示重合部分。(PorterDuff.Mode:一個強大的圖像轉換模式,使用它,可以使用圖像合成的16條Porter-Duff規則的任意一條來控制Paint如何與已有的Canvas圖像進行交互。哈哈,說人話就是用來控制圖層與圖層之間如何覆蓋,覆蓋之后取哪部分顯示到畫布上,有興趣的可以自行百度,這里只用到了兩種模式。)
下面直接上代碼和效果圖:
在構造方法里處理圖層關系:
public CircleFramedDrawable(Bitmap icon, int size) {
super();
mSize = size;
mBitmap = Bitmap.createBitmap(mSize, mSize, Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(mBitmap);
final int width = icon.getWidth();
final int height = icon.getHeight();
final int square = Math.min(width, height);
final Rect cropRect = new Rect((width - square) / 2, (height - square) / 2, square, square);
final RectF circleRect = new RectF(0f, 0f, mSize, mSize);
final Path fillPath = new Path();
//path.addArc方法用于繪制圓弧,這個圓弧取自RectF矩形的內接橢圓上的一部分,圓弧長度由后兩個角度參數決定
fillPath.addArc(circleRect, 0f, 360f);
//PorterDuff.Mode.CLEAR:清除畫布(所繪制不會提交到畫布上)
canvas.drawColor(0, PorterDuff.Mode.CLEAR);
// opaque circle matte
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.FILL);
canvas.drawPath(fillPath, mPaint);
// mask in the icon where the bitmap is opaque(不透明)
//PorterDuff.Mode.SRC_IN:兩者相交的地方繪制源圖
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(icon, cropRect, circleRect, mPaint);
// prepare paint for frame drawing
// 別忘記還原畫筆~
mPaint.setXfermode(null);
mScale = 1f;
mSrcRect = new Rect(0, 0, mSize, mSize);
mDstRect = new RectF(0, 0, mSize, mSize);
}
當然支持圖片的縮放啦:
@Override
public void draw(Canvas canvas) {
//縮放處理
final float inside = mScale * mSize;
final float pad = (mSize - inside) / 2f;
//將矩形的坐標設置為縮放后指定的值
mDstRect.set(pad, pad, mSize - pad, mSize - pad);
//第一個mSrcRect代表要繪制的bitmap區域,第二個mDstRect代表的是要將bitmap繪制在屏幕的什么地方
canvas.drawBitmap(mBitmap, mSrcRect, mDstRect, null);
}
獲取drawable時傳入我們想要的大小就可以了
public static CircleFramedDrawable getInstance(Context context, Bitmap icon,float size) {
Resources res = context.getResources();
float iconSize = px2dip(context,size);
CircleFramedDrawable instance = new CircleFramedDrawable(icon, (int) iconSize);
return instance;
}
怎么使用?
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.workingdog);
mIcon.setImageDrawable(CircleFramedDrawable.getInstance(this,bitmap,800));
}
所以可以不用修改項目中的布局文件,直接加一個Drawable類就能在任何時候轉換圖片至圓形了!
效果圖:
來自:http://www.jianshu.com/p/8d9757e216ca
本文由用戶 LayRosario 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!