一蝙砌、前言
在開發(fā)中遇到這么一個(gè)問題。我們app注冊時(shí)候使用了微博的頭像阅悍,但是目前微博用戶初始頭像(未曾設(shè)置過頭像的時(shí)候)返回的是gif格式附鸽,而在我們的某個(gè)地方的頭像顯示控件SimpleDraweeView中需要使用圓形特性,但是的Fresco使用中g(shù)if圖無法實(shí)現(xiàn)圓形文虏。網(wǎng)上也有方案侣诺,當(dāng)背景不是純色,F(xiàn)resco解決gif不能轉(zhuǎn)圓形問題的終極方案氧秘,思路或許可行年鸳,但是太過麻煩。然后就考慮使用自定義view實(shí)現(xiàn)丸相。過程中發(fā)現(xiàn)一個(gè)簡單的圓形方案搔确,過程用到Canvas的layer知識,在此學(xué)習(xí)記錄下來。
二膳算、Canvas與Layer
- Canvas座硕,即畫布。Canvas有一系列簡單的操作方法提供涕蜂,有 平移(translate)华匾,旋轉(zhuǎn)(rotate),縮放(scale),錯(cuò)切(skew)机隙,裁剪(clip)蜘拉,保存(save),保存圖層(saveLayer)有鹿,恢復(fù)(restore),恢復(fù)到指定狀態(tài)(restoreToCount)等旭旭。
關(guān)于操作,在這篇文章中講的很透徹了葱跋,我就不一一累述您机。Canvas的變換 - Layer,即圖層年局。詳細(xì)了解际看,參考Canvas的saveLayer理解
三、圓形頭像實(shí)現(xiàn)思路
利用Xfermode實(shí)現(xiàn)只繪制自己想要的區(qū)域矢否,即圓形部分仲闽。更多在 Android-PorterDuffXfermode的正確使用方式
package com.zii.canvas.layer;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.support.annotation.UiThread;
import android.util.AttributeSet;
import com.facebook.drawee.view.SimpleDraweeView;
import com.zii.canvas.R;
public class GenderAvatarView extends SimpleDraweeView {
private Paint mDstPaint;
private Paint mSrcPaint;
private Paint mOverlayPaint;
private Bitmap mBitmapFemale;
private Bitmap mBitmapMale;
private Bitmap mBitmapGender;
private RectF mRoundRectF;
private boolean mIsMale;
public GenderAvatarView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public GenderAvatarView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
mDstPaint = new Paint();
mDstPaint.setAntiAlias(true);
mSrcPaint = new Paint();
mSrcPaint.setAntiAlias(true);
mSrcPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));//重點(diǎn)
mOverlayPaint = new Paint();
mOverlayPaint.setAntiAlias(true);
mBitmapFemale = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.ic_setting_gender_lady);
mBitmapMale = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.ic_setting_gender_man);
mRoundRectF = new RectF();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mBitmapGender = mIsMale ? mBitmapMale : mBitmapFemale;
mBitmapGender = zoomBitmap(mBitmapGender, w, h);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
mRoundRectF.set(0, 0, getWidth(), getHeight());
}
@Override
protected void onDraw(Canvas canvas) {
canvas.saveLayer(mRoundRectF, mDstPaint, Canvas.ALL_SAVE_FLAG);
canvas.drawRoundRect(mRoundRectF, mRoundRectF.centerX(), mRoundRectF.centerY(), mDstPaint);//dst,圓形區(qū)域
canvas.saveLayer(mRoundRectF, mSrcPaint, Canvas.ALL_SAVE_FLAG);//paint使用src_in模式僵朗,與上一次相交保留src顯示
super.onDraw(canvas);//src赖欣,頭像
canvas.restore();
canvas.drawBitmap(mBitmapGender, 0, 0, mOverlayPaint);//overlay
}
private Bitmap zoomBitmap(Bitmap src, int dstWidth, int dstHeight) {
if (src == null || (src.getWidth() == dstWidth && src.getHeight() == dstHeight)) {
return src;
}
return Bitmap.createScaledBitmap(src, dstWidth, dstHeight, true);
}
@UiThread
public void setGender(boolean isMale) {
this.mIsMale = isMale;
invalidate();
}
}
四、后記
emmm验庙,很簡單顶吮,是不是?同時(shí)也解決了fresco的SimpleDraweeView對gif不實(shí)現(xiàn)圓形的特性粪薛,同時(shí)根據(jù)我自己需要增加性別圈圈的覆蓋物了悴了。