Android編程實(shí)現(xiàn)自定義ImageView圓圖功能的方法
本文實(shí)例講述了Android編程實(shí)現(xiàn)自定義ImageView圓圖功能的方法。分享給大家供大家參考,具體如下:
首先很感謝開源項(xiàng)目Universal Image Loader圖片加載框架。之前也看過一段時(shí)間框架源碼,但是卻沒有時(shí)間進(jìn)行知識(shí)點(diǎn)的總結(jié)。
今天項(xiàng)目遇到了需要實(shí)現(xiàn)圓頭像的編輯顯示,Universal就已經(jīng)提供了這個(gè)顯示RoundedBitmapDisplayer這個(gè)類實(shí)現(xiàn)了圓圖功能。看它的代碼可以發(fā)現(xiàn)是實(shí)現(xiàn)的Drawable
public static class RoundedDrawable extends Drawable { protected final float cornerRadius; protected final int margin; protected final RectF mRect = new RectF(), mBitmapRect; protected final BitmapShader bitmapShader; protected final Paint paint; public RoundedDrawable(Bitmap bitmap, int cornerRadius, int margin) { this.cornerRadius = cornerRadius; this.margin = margin; bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); mBitmapRect = new RectF (margin, margin, bitmap.getWidth() - margin, bitmap.getHeight() - margin); paint = new Paint(); paint.setAntiAlias(true); paint.setShader(bitmapShader); } @Override protected void onBoundsChange(Rect bounds) { super.onBoundsChange(bounds); mRect.set(margin, margin, bounds.width() - margin, bounds.height() - margin); // Resize the original bitmap to fit the new bound Matrix shaderMatrix = new Matrix(); shaderMatrix.setRectToRect(mBitmapRect, mRect, Matrix.ScaleToFit.FILL); bitmapShader.setLocalMatrix(shaderMatrix); } @Override public void draw(Canvas canvas) { canvas.drawRoundRect(mRect, cornerRadius, cornerRadius, paint); } @Override public int getOpacity() { return PixelFormat.TRANSLUCENT; } @Override public void setAlpha(int alpha) { paint.setAlpha(alpha); } @Override public void setColorFilter(ColorFilter cf) { paint.setColorFilter(cf); } }
其實(shí)總結(jié)下來,上面圓圖實(shí)現(xiàn)步驟就是:
1、通過bitmap初始化位圖著色器BitmapShader類
2、計(jì)算bitmap原始圖片的rect
3、計(jì)算放置圖片需要的rect
4、使用Matrix類對(duì)兩個(gè)rect進(jìn)行壓縮,然后復(fù)制給BitmapShader著色器里去。最后是畫布畫圖。
(剛開始一直以為shader是陰影的意思,原來有道一下是著色器的意思,這個(gè)翻譯其實(shí)對(duì)我理解代碼還是很重要的,所以不要想當(dāng)然,要勤奮點(diǎn),這個(gè)是優(yōu)秀程序員必備要素。)
最后我要實(shí)現(xiàn)的是繼承ImageView實(shí)現(xiàn)圓圖
public class URoundedImageView extends ImageView { private Paint mBitmapPaint,mBackgroundPaint; private BitmapShader mBitmapShader; private RectF mBitmapRect , mRect; private int borderWidth; private Bitmap mBitmap; private Matrix shaderMatrix; public URoundedImageView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } public URoundedImageView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public URoundedImageView(Context context) { super(context); init(); } private void init(){ mBitmapPaint = new Paint(); mBitmapPaint.setAntiAlias(true); mBackgroundPaint = new Paint(); mBackgroundPaint.setAntiAlias(true); mBackgroundPaint.setColor(Color.WHITE); borderWidth = 5; mRect = new RectF(); shaderMatrix = new Matrix(); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { // TODO Auto-generated method stub super.onLayout(changed, left, top, right, bottom); } @Override protected void onDraw(Canvas canvas) { mBitmap = ((BitmapDrawable) getDrawable()).getBitmap(); if (getWidth() == 0 || getHeight() == 0 || mBitmap == null) { return; } int w = getWidth(); int h = getHeight(); int radius = Math.min(w, h) / 2; canvas.drawCircle(w / 2, h / 2, radius, mBackgroundPaint); //傳入bitmap初始化位圖著色器 if (mBitmapShader == null) { mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); } if (mBitmapRect == null) { mBitmapRect = new RectF(borderWidth, borderWidth, mBitmap.getWidth() - borderWidth, mBitmap.getHeight() - borderWidth); } mBitmapPaint.setShader(mBitmapShader); mRect.set(borderWidth, borderWidth, w - borderWidth, h - borderWidth); //對(duì)bitmap原始圖進(jìn)行縮放 shaderMatrix.setRectToRect(mBitmapRect, mRect, Matrix.ScaleToFit.FILL); mBitmapShader.setLocalMatrix(shaderMatrix); canvas.drawRoundRect(mRect, radius, radius, mBitmapPaint); } }
剛開始寫的不夠規(guī)范,直接在ondraw方法里面new一些需要的對(duì)象,lint提醒我們Avoid object allocations during draw/layout operations (preallocate and reuse instead)這個(gè)warning。因?yàn)閛ndraw會(huì)不斷調(diào)用,如果一直new對(duì)象的話會(huì)吃內(nèi)存。所以為了避免重復(fù)new對(duì)象,根據(jù)自己的需求進(jìn)行判空操作。具體根據(jù)自己需求來優(yōu)化代碼,有時(shí)候?yàn)榱诉_(dá)到需求也沒辦法做到在ondraw方法里不出現(xiàn)重復(fù)new對(duì)象的現(xiàn)象。
總結(jié):多參考優(yōu)秀的開源項(xiàng)目,用正確的方法做正確的事情!
更多關(guān)于Android相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Android圖形與圖像處理技巧總結(jié)》、《Android開發(fā)入門與進(jìn)階教程》、《Android調(diào)試技巧與常見問題解決方法匯總》、《Android基本組件用法總結(jié)》、《Android視圖View技巧總結(jié)》、《Android布局layout技巧總結(jié)》及《Android控件用法總結(jié)》
希望本文所述對(duì)大家Android程序設(shè)計(jì)有所幫助。
- Android自定義ImageView實(shí)現(xiàn)自動(dòng)放大縮小動(dòng)畫
- Android自定義圓角ImageView控件
- Android 自定義imageview實(shí)現(xiàn)圖片縮放實(shí)例詳解
- Android自定義控件之圓形、圓角ImageView
- Android自定義GestureDetector實(shí)現(xiàn)手勢ImageView
- android自定義ImageView仿圖片上傳示例
- Android自定義ImageView實(shí)現(xiàn)在圖片上添加圖層效果
- Android通過自定義ImageView控件實(shí)現(xiàn)圖片的縮放和拖動(dòng)的實(shí)現(xiàn)代碼
- Android 自定義圓形頭像CircleImageView支持加載網(wǎng)絡(luò)圖片的實(shí)現(xiàn)代碼
- Android自定義圓角ImageView
- Android布局自定義Shap圓形ImageView可以單獨(dú)設(shè)置背景與圖片
相關(guān)文章
安裝android開發(fā)環(huán)境原始版(windows版)
安裝android開發(fā)環(huán)境原始版(windows版)的詳細(xì)步驟2013-03-03Android使用開源組件PagerBottomTabStrip實(shí)現(xiàn)底部菜單和頂部導(dǎo)航功能
這篇文章主要介紹了Android使用PagerBottomTabStrip實(shí)現(xiàn)底部菜單和頂部導(dǎo)航功能,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-08-08取消Android Studio項(xiàng)目與SVN關(guān)聯(lián)的方法
今天小編就為大家分享一篇關(guān)于取消Android Studio項(xiàng)目與SVN關(guān)聯(lián)的方法,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2018-12-12詳解關(guān)于Android Studio中安裝和gradle的一些坑
本篇文章主要介紹了關(guān)于Android Studio中安裝和gradle的一些坑,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-10-10Android編程設(shè)計(jì)模式之訪問者模式詳解
這篇文章主要介紹了Android編程設(shè)計(jì)模式之訪問者模式,詳細(xì)分析了訪問者模式的概念、功能、原理、使用場景并結(jié)合實(shí)例形式給出了Android訪問者模式的具體實(shí)現(xiàn)技巧與相關(guān)操作注意事項(xiàng),需要的朋友可以參考下2017-12-12Android基于widget組件實(shí)現(xiàn)物體移動(dòng)/控件拖動(dòng)功能示例
這篇文章主要介紹了Android基于widget組件實(shí)現(xiàn)物體移動(dòng)/控件拖動(dòng)功能,結(jié)合實(shí)例形式分析了widget組件在桌面應(yīng)用中的事件響應(yīng)與屬性動(dòng)態(tài)操作相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2016-10-10Android實(shí)現(xiàn)拍照、選擇圖片并裁剪圖片功能
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)拍照、選擇圖片并裁剪圖片功能的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-05-05Kotlin圖文并茂講解續(xù)體與續(xù)體攔截器和調(diào)度器
這篇文章主要介紹了Kotlin開發(fā)中續(xù)體與續(xù)體攔截器和調(diào)度器的相關(guān)使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08Android組件Glide實(shí)現(xiàn)圖片平滑滾動(dòng)效果
這篇文章主要介紹了Android組件Glide實(shí)現(xiàn)圖片平滑滾動(dòng)效果的相關(guān)資料,具有一定的參考價(jià)值,需要的朋友可以參考下2016-07-07