Android自定義View之繪制圓形頭像功能
前言
做APP應(yīng)用開(kāi)發(fā)的時(shí)候,用戶頭像肯定是必不可少的,但是90%以上的需求頭像都是圓形的。那么,如何通過(guò)自定義View的方式實(shí)現(xiàn)圓形頭像呢,那么,本片博文會(huì)告訴你不僅僅是實(shí)現(xiàn)過(guò)程。一定會(huì)有意想不到的收獲哦!
最終效果
國(guó)際慣例,我們先來(lái)看最終實(shí)現(xiàn)的效果圖
自定義RoundImageView繼承自ImageView
public class RoundImageView extends ImageView { public RoundImageView(Context context) { super(context); } public RoundImageView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); } public RoundImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } }
不知你是否注意過(guò)每當(dāng)我們繼承自View的時(shí)候,系統(tǒng)都會(huì)提示我們覆蓋重寫4個(gè)構(gòu)造方法,這里我們只覆蓋了三個(gè),然后就開(kāi)始在每個(gè)構(gòu)造方法中進(jìn)行初始化,那么,是不是每次都會(huì)調(diào)用所有的構(gòu)造方法呢,如果不是,這三個(gè)構(gòu)造方法又會(huì)什么時(shí)候調(diào)用呢?下面我們來(lái)通過(guò)例子來(lái)驗(yàn)證。
使用自定義View無(wú)非就兩種情況下,第一種就是直接在xml布局中使用,另一種就是在Activity中new出來(lái),下面我們分別使用上述兩種方式,為了便于觀察我們?cè)谌齻€(gè)構(gòu)造方法中分別加入一行打印。
首先我們?cè)趚ml直接使用,運(yùn)行打印如下:
com.example.roundimageview D/RoundImageView: RoundImageView: 兩個(gè)參數(shù)的構(gòu)造方法
然后我們?cè)贏ctivity中,new一個(gè)RoundImageView
roundImageView = RoundImageView(this@MainActivity) roundImageView = RoundImageView(this@MainActivity, null) roundImageView = RoundImageView(this@MainActivity, null,0)
運(yùn)行打印日志如下:
結(jié)論:自定義View當(dāng)在xml中使用,使用的是第二個(gè)構(gòu)造方法,當(dāng)在Activity中使用時(shí),實(shí)例化時(shí)傳入幾個(gè)參數(shù)調(diào)用的就是含有幾個(gè)參數(shù)的構(gòu)造方法。
實(shí)現(xiàn)圓形頭像的思想
我始終認(rèn)為自定義View的難度只在于它的實(shí)現(xiàn)思想,通常我們遇到問(wèn)題的時(shí)候,并不是Google不到,而是壓根就不知道這個(gè)問(wèn)題該去如何Google,如果知道了問(wèn)題所產(chǎn)生的原因,其實(shí)問(wèn)題已經(jīng)迎刃而解了,最怕的是不知道問(wèn)題為什么會(huì)產(chǎn)生。
實(shí)現(xiàn)圓形頭像的思想一個(gè)簡(jiǎn)單的圖就可以表示了。
矩形區(qū)域是完整的圖片,圓形區(qū)域就是我們最終顯示的頭像區(qū)域,那么就很簡(jiǎn)單了,圓形區(qū)域與矩形區(qū)域相交,取并集區(qū)域?在矩形中畫一個(gè)與矩形長(zhǎng)或?qū)捪嗲械膱A,而圓的直徑是長(zhǎng)或?qū)捿^短的一邊。
編碼實(shí)現(xiàn)
獲取原有頭像的bitmap
首先我們需要獲取設(shè)置頭像的bitmap,我們可以直接通過(guò)API來(lái)獲取設(shè)置的圖片資源,
drawable = this.getDrawable();
再將圖片資源轉(zhuǎn)化為bitmap
首先我們判斷drawable是否為空,如果為空說(shuō)明用戶沒(méi)有設(shè)置,拋出資源未找到的異常。
if (drawable == null) { throw new Resources.NotFoundException("Image resource not set"); }
如果不為空,我們創(chuàng)建一個(gè)與圖片資源大小相等的bitmap,并將bitmap繪制出來(lái),代碼如下所示:
bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); drawable.draw(canvas);
繪制圓形bitmap
通過(guò)上面的代碼,我們得到了原有的bitmap圖像,緊接著我們需要繪制圓形的bitmap,與上面類似,首先創(chuàng)建一個(gè)和bitmap大小一致的位圖
circleBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
我們畫一個(gè)與bitmap等大的矩形
Paint paint = new Paint(); Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); canvas.drawRect(rect,paint); RectF rectF = new RectF(rect);
將較短的一邊設(shè)置圓的半徑
float roundRa = 0.0f; if (bitmap.getWidth() > bitmap.getHeight()) { roundRa = bitmap.getHeight() / 2.0f; } else { roundRa = bitmap.getWidth() / 2.0f; }
設(shè)置paint和canvas屬性
paint.setAntiAlias(true); canvas.drawARGB(0, 0, 0, 0); paint.setColor(Color.WHITE); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawARGB將繪制裁剪設(shè)為透明,paint.setXfermode
中的PorterDuffXfermode
類很強(qiáng)大,后面我們會(huì)單獨(dú)一篇文章講解。
最終我們重新將bitmap繪制出來(lái)即可
canvas.drawBitmap(bitmap, rect, rect, paint);
繪制部分完整代碼如下所示:
* 獲取圓形裁剪的bitmap * * @param bitmap 原bitmap */ private Bitmap getCircleBitmap(Bitmap bitmap) { circleBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(circleBitmap); Paint paint = new Paint(); Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); RectF rectF = new RectF(rect); float roundRa = 0.0f; if (bitmap.getWidth() > bitmap.getHeight()) { roundRa = bitmap.getHeight() / 2.0f; } else { roundRa = bitmap.getWidth() / 2.0f; } paint.setAntiAlias(true); canvas.drawARGB(0, 0, 0, 0); paint.setColor(Color.GRAY); canvas.drawRoundRect(rectF, roundRa, roundRa, paint); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); canvas.drawBitmap(bitmap, rect, rect, paint); return circleBitmap; }
設(shè)置最終的bitmap
得到bitma后我們直接重新設(shè)置即可顯示
setImageBitmap(getCircleBitmap(bitmap));
本實(shí)例較為簡(jiǎn)單,就不貼所有代碼了,如有需要留言郵箱即可,如有紕漏之處,歡迎指正!晚安!
9.15 22:17 更新
代碼已上傳github:https://github.com/huanglinqing123/RoundImageView
總結(jié)
以上所述是小編給大家介紹的Android自定義View之繪制圓形頭像功能,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)我們網(wǎng)站的支持!
如果你覺(jué)得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!
上一篇:Android實(shí)現(xiàn)雙擊返回鍵退出應(yīng)用實(shí)現(xiàn)方法詳解
欄 目:Android
下一篇:沒(méi)有了
本文標(biāo)題:Android自定義View之繪制圓形頭像功能
本文地址:http://mengdiqiu.com.cn/a1/Android/9209.html
您可能感興趣的文章
- 01-10Android實(shí)現(xiàn)雙擊返回鍵退出應(yīng)用實(shí)現(xiàn)方法詳解
- 01-10android實(shí)現(xiàn)記住用戶名和密碼以及自動(dòng)登錄
- 01-10android實(shí)現(xiàn)簡(jiǎn)單計(jì)算器功能
- 01-10Android 友盟第三方登錄與分享的實(shí)現(xiàn)代碼
- 01-10C++自定義API函數(shù)實(shí)現(xiàn)大數(shù)相乘算法
- 01-10android實(shí)現(xiàn)指紋識(shí)別功能
- 01-10Emoji表情在Android JNI中的兼容性問(wèn)題詳解
- 01-10Android實(shí)現(xiàn)圓形漸變加載進(jìn)度條
- 01-10android開(kāi)發(fā)環(huán)境中SDK文件夾下的所需內(nèi)容詳解
- 01-10android異步消息機(jī)制 源碼層面徹底解析(1)


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹(shù)的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 01-10Android自定義View之繪制圓形頭像功能
- 01-10Android實(shí)現(xiàn)雙擊返回鍵退出應(yīng)用實(shí)現(xiàn)方
- 01-10android實(shí)現(xiàn)簡(jiǎn)單計(jì)算器功能
- 01-10android實(shí)現(xiàn)記住用戶名和密碼以及自動(dòng)
- 01-10C++自定義API函數(shù)實(shí)現(xiàn)大數(shù)相乘算法
- 01-10Android 友盟第三方登錄與分享的實(shí)現(xiàn)代
- 01-10android實(shí)現(xiàn)指紋識(shí)別功能
- 01-10如何給Flutter界面切換實(shí)現(xiàn)點(diǎn)特效
- 01-10Android實(shí)現(xiàn)圓形漸變加載進(jìn)度條
- 01-10Emoji表情在Android JNI中的兼容性問(wèn)題詳
隨機(jī)閱讀
- 01-10SublimeText編譯C開(kāi)發(fā)環(huán)境設(shè)置
- 01-10delphi制作wav文件的方法
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 01-10C#中split用法實(shí)例總結(jié)
- 04-02jquery與jsp,用jquery
- 01-11Mac OSX 打開(kāi)原生自帶讀寫NTFS功能(圖文
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子