1. 程式人生 > >圓形圖片(或者給頭像加個描邊)CircleImageView的使用和分析

圓形圖片(或者給頭像加個描邊)CircleImageView的使用和分析

在專案開發中,我們經常需要用到圓形圖片效果,典型案例是使用者頭像的顯示。

如圖所示。


下面我們使用開源控制元件CircleImageView來實現該效果。

CircleImageView專案下載地址:
https://github.com/hdodenhof/CircleImageView

(1).CircleImageView的使用

首先我們將CircleImageView新增到gradle。

  1. dependencies {  
  2.     compile 'de.hdodenhof:circleimageview:2.1.0'  
  3. }  

然後看一下自定義屬性attrs:

  1. <declare-styleablename="CircleImageView"
    >
  2.         <attrname="civ_border_width"format="dimension"/>
  3.         <attrname="civ_border_color"format="color"/>
  4.         <attrname="civ_border_overlay"format="boolean"/>
  5.         <attrname="civ_fill_color"format="color"/>
  6.     </declare-styleable>
屬性介紹:civ_border_width:   設定邊框的寬度,預設為0,即無邊框。

civ_border_color:    設定邊框的顏色,預設為黑色。
civ_border_overlay:設定邊框是否覆蓋在圖片上,預設為false,即邊框在圖片外圈。
civ_fill_color:           設定圖片的底色,預設透明。

接下來在佈局檔案中引入CircleImageView。(給頭像加描邊使用circleimageview:civ_border_color和circleimageview:civ_border_width即可
  1. <de.hdodenhof.circleimageview.CircleImageView
  2.         xmlns:circleimageview
    ="http://schemas.android.com/apk/res-auto"
  3.         android:id="@+id/imageview"
  4.         android:layout_width="wrap_content"
  5.         android:layout_height="wrap_content"
  6.         android:src="@drawable/profile"
  7.         circleimageview:civ_border_color="@android:color/holo_red_light"
  8.         circleimageview:civ_border_overlay="false"
  9.         circleimageview:civ_border_width="2dp"
  10.         circleimageview:civ_fill_color="@android:color/holo_blue_light"/>

注意:CircleImageView的預設ScaleType為CENTER_CROP,且只能為CENTER_CROP。

(2).CircleImageView的原始碼分析

通過檢視原始碼可以看到,內部核心方法主要是對Paint、Canvas、BitmapShader、Matrix、RectF類的使用。

我們分析一下程式碼的執行流程。首先可以通過佈局檔案中的src屬性或者java程式碼的setImageXxx()方法來設定圖片,控制元件在構造方法中獲取到自定義屬性的引數值,然後會執行到setup()這個方法。

我們來分析一下setup()方法,該方法是CircleImageView的核心。

  1. privatevoid setup() {  
  2.         // mReady和mSetupPending屬性,在構造方法和setup()方法都有引用和賦值
  3.         // 目的是確保setup()內部邏輯的執行是在構造方法執行完畢之後,即獲取到自定義屬性引數之後
  4.         if (!mReady) {  
  5.             mSetupPending = true;  
  6.             return;  
  7.         }  
  8.         // 圖片寬高為0,不往下執行
  9.         if (getWidth() == 0 && getHeight() == 0) {  
  10.             return;  
  11.         }  
  12.         // 只有傳入了圖片,才會往下執行
  13.         if (mBitmap == null) {  
  14.             invalidate();  
  15.             return;  
  16.         }  
  17.         // BitmapShader類用來渲染頭像
  18.         // 引數1:要處理的bitmap物件,引數2和3:指定模式為對圖片的邊緣進行拉伸
  19.         mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);  
  20.         // 圖片畫筆:設定抗鋸齒
  21.         mBitmapPaint.setAntiAlias(true);  
  22.         // 圖片畫筆:設定渲染器
  23.         mBitmapPaint.setShader(mBitmapShader);  
  24.         // 邊框畫筆:設定樣式為描邊
  25.         mBorderPaint.setStyle(Paint.Style.STROKE);  
  26.         // 邊框畫筆:設定抗鋸齒
  27.         mBorderPaint.setAntiAlias(true);  
  28.         // 邊框畫筆:設定顏色值
  29.         mBorderPaint.setColor(mBorderColor);  
  30.         // 邊框畫筆:設定寬度
  31.         mBorderPaint.setStrokeWidth(mBorderWidth);  
  32.         // 底色畫筆:設定樣式為填充
  33.         mFillPaint.setStyle(Paint.Style.FILL);  
  34.         // 底色畫筆:設定抗鋸齒
  35.         mFillPaint.setAntiAlias(true);  
  36.         // 底色畫筆:設定顏色
  37.         mFillPaint.setColor(mFillColor);  
  38.         // 獲取原圖的高度
  39.         mBitmapHeight = mBitmap.getHeight();  
  40.         // 獲取原圖的寬度
  41.         mBitmapWidth = mBitmap.getWidth();  
  42.         // 設定邊框的顯示區域
  43.         mBorderRect.set(calculateBounds());  
  44.         // 計算邊框的半徑
  45.         mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2.0f, (mBorderRect.width() - mBorderWidth) / 2.0f);  
  46.         // 設定圖片的顯示區域為上面計算出來的mBorderRect
  47.         mDrawableRect.set(mBorderRect);  
  48.         // 如果邊框不是覆蓋在圖片之上,並且邊框寬度大於0,擴大圖片的顯示區域,增加mBorderWidth-1
  49.         if (!mBorderOverlay && mBorderWidth > 0) {  
  50.             mDrawableRect.inset(mBorderWidth - 1.0f, mBorderWidth - 1.0f);  
  51.         }  
  52.         // 計算圖片的半徑
  53.         mDrawableRadius = Math.min(mDrawableRect.height() / 2.0f, mDrawableRect.width() / 2.0f);  
  54.         // 該方法內部只有一行程式碼,mBitmapPaint.setColorFilter(mColorFilter),給bitmap新增濾鏡
  55.         applyColorFilter();  
  56.         updateShaderMatrix();// 下文會介紹
  57.         invalidate();// 下文會介紹
  58.     }  

上述setup()方法中使用到了updateShaderMatrix()方法。
  1. privatevoid updateShaderMatrix() {  
  2.         float scale;  
  3.         float dx = 0;  
  4.         float dy = 0;  
  5.         mShaderMatrix.set(null);  
  6.         // 這裡取最小的縮放比例,以儘量保證圖片的質量
  7.         // 判斷如果寬度的比例大於高度的比例,取高度的縮放比,平移x軸方向
  8.         // 否則取寬度的縮放比,平移y軸方向
  9.         if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) {  
  10.             scale = mDrawableRect.height() / (float) mBitmapHeight;  
  11.             dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f;  
  12.         } else {  
  13.             scale = mDrawableRect.width() / (float) mBitmapWidth;  
  14.             dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f;  
  15.         }  
  16. 相關推薦

    圓形圖片或者頭像CircleImageView的使用分析

    在專案開發中,我們經常需要用到圓形圖片效果,典型案例是使用者頭像的顯示。如圖所示。下面我們使用開源控制元件CircleImageView來實現該效果。CircleImageView專案下載地址:https://github.com/hdodenhof/CircleImageV

    網路【一】 python連結,讓預設瀏覽器或者指定瀏覽器開啟連結

    webbrowser — Convenient Web-browser controller The webbrowser module provides a high-level interface to allow displaying Web-based docu

    如何高性能的 UIImageView 圓角?

    上下 mcu ask ons with contex sel rim 方案 不好的解決方案 使用下面的方式會強制Core Animation提前渲染屏幕的離屏繪制, 而離屏繪制就會給性能帶來負面影響,會有卡頓的現象出現 self.view.layer.cornerR

    用 Python 程序進度條,讓你的看起來更炫酷?

    image 進度條 hub 一行 ref 當前 標準輸出 alt 操作 對於開發或者運維來說,使用 Python 去完成一些跑批任務,或者做一些監控事件是非常正常的情況。那麽如何有效地監控任務的進度?除了在任務中加上 Log 外,還能不能有另一種方式來了解任務進展到哪一步了

    移動端tabbar按鈕滑動div橫向滾動條

    手寫程式碼乾貨,已測試(請在移動端中開啟除錯) <!DOCTYPE html> <html> <head> <title>底部tabbar欄滑動</title> <script type="text/ja

    OnPaint HDC 引數

    MFC的視窗繪製函式是 CWnd::OnPaint   afx_msg void OnPaint( ); 而 WM_PAINT 訊息可以是 WM_PAINT  hdc = (HDC) wParam; 就是說OnPaint可以帶個 HDC 的引數. // in head fi

    < C++ > initializer list 初始化列表建構函式後面冒號的解釋

    Keypoint : 呼叫父類的建構函式(一般為有參建構函式),初始化類中的成員。 C++ primer 5th edition: Remember When creating an object of a derived class, a program first

    C語言:幾不常用或者說可能出錯的如const的type qualifier

    幾個不常用(除const和volatile外)的type qualifiers,const和volatile應該算是最熟悉的了,但是其他的幾個就不大容易在程式碼中發現,寫下來順便學習下描述:這幾個type qualifiers的使用範圍是有限制的,const和volatile

    linux使用者操作某個目錄的許可權

    [[email protected] ~]# chown -R root:wangchong /usr/local/apache2/htdocs/ [[email protecte

    逆序n個數中m逆序

    .com light ostream size 逆序對數 逆序對 std ios pac 逆序對數列 對於一個數列{ai},如果有i<j且ai>aj,那麽我們稱ai與aj為一對逆序對數。若對於任意一個由1~n自然數組成的 數列,可以很容易求出有多少個逆序對數

    如何在當前目錄下快速打開cmd或者以管理員的身份打開

    方便 空白 tutorial light 很多 -1 mage for pen 1.在當前目錄下,按住shift鍵+點擊右鍵,選擇在此處打開命令窗口 很多時候我們需要打開命令行然後進入到相應目錄進行一些操作。 常規的做法是: D:\foo\bar", 然後輸入cd 再把復

    Windows RabbitMQ 添用戶、設置角色權限 包含無法添的錯誤處理

    lan mini -c 根據 cookie 添加 官網 ins In 添加賬號密碼 rabbitmqctl.bat add_user test 123456 添加角色 rabbitmqctl.bat set_user_tags test administrator 授

    實驗吧 看起來有點難手工註入sqlmap註入

    wid ati 實驗 alt 成功 技術 pytho code login 嗯~打開題目看見一個逼格有點高的圖 查看網頁源代碼,表單以get的方式傳送三個參數(admin,pass,action)給index.php,但是限制了兩個輸入框的最大長度是10,這個是前端的限制

    Conquer a New Region並查集維護根節點

    The wheel of the history rolling forward, our king conquered a new region in a distant continent. There are N towns (numbered from 1 to N) in this r

    每日一題--LeetCode 387 字串中的第一唯一字元java

    題目描述: 程式碼如下: class Solution { public int firstUniqChar(String s) { String tmp=s; char []data=tmp.toCharArray(); if(

    svg動畫跟著圖片

    效果圖   <!DOCTYPE html> <html lang="en">     <head>         <meta charse

    kali系統固化到固態硬盤小記贈送廣大折騰黨的筆記

    管理 ssd 區號 usb3.0 掛載 install 數據 格式化 比較 1.首先你需要一個移動硬盤和一個移動硬盤盒子(一根數據轉換線,一般買盒子商家會贈送的) SSD硬盤要事先格式化一下格式,不然識別不出來 2.準備好Kali鏡像,傳送門在這裏https://www.k

    kali系統固化到固態硬碟小記贈送廣大折騰黨的筆記

    1.首先你需要一個行動硬碟和一個行動硬碟盒子(一根資料轉換線,一般買盒子商家會贈送的) SSD硬碟要事先格式化一下格式,不然識別不出來 2.準備好Kali映象,傳送門在這裡https://www.kali.org/,安裝好VM虛擬機器,值得一說的是固態硬碟,一定要開啟虛擬機器的USB3.0埠 這裡配

    Linux環境下多庫svn安裝與配置獨立庫,多配置檔案

    [先在伺服器中開啟放行 3690 埠!!!] (1)檢視是否已經安裝了svn 命令:svnserve --version 沒有安裝,出現下面資訊-> 已經安裝,出現下面版本資訊-> 檢視安裝svn的路徑資訊:rpm -ql subversion

    工藝路線建立BAPI BAPI_ROUTING_CREATE,批量建立時無法連續建立多工藝路線只成功建立第一工藝路線

    相關T-CODE: CA01 CA02 CA03 BAPI傳入引數如下所示 CLEAR:lv_group,lv_groupcounter,lt_return. CALL FUNCTION 'BAPI_ROUTING_CREATE' * EXPOR