Android自定義View之繪製圓形頭像功能

這篇文章主要介紹了Android自定義View之繪製圓形頭像功能,本文給大家介紹的非常詳細,具有一定的參考借鑑價值,需要的朋友可以參考下

前言

做APP應用開發的時候,用戶頭像肯定是必不可少的,但是90%以上的需求頭像都是圓形的。那麼,如何通過自定義View的方式實現圓形頭像呢,那麼,本片博文會告訴你不僅僅是實現過程。一定會有意想不到的收穫哦!

最終效果

國際慣例,我們先來看最終實現的效果圖

自定義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);
  }
}

 不知你是否注意過每當我們繼承自View的時候,系統都會提示我們覆蓋重寫4個構造方法,這裏我們只覆蓋了三個,然後就開始在每個構造方法中進行初始化,那麼,是不是每次都會調用所有的構造方法呢,如果不是,這三個構造方法又會什麼時候調用呢?下面我們來通過例子來驗證。

使用自定義View無非就兩種情況下,第一種就是直接在xml佈局中使用,另一種就是在Activity中new出來,下面我們分別使用上述兩種方式,爲了便於觀察我們在三個構造方法中分別加入一行打印。

首先我們在xml直接使用,運行打印如下:

com.example.roundimageview D/RoundImageView: RoundImageView: 兩個參數的構造方法

然後我們在Activity中,new一個RoundImageView

roundImageView = RoundImageView(this@MainActivity)
roundImageView = RoundImageView(this@MainActivity, null)
roundImageView = RoundImageView(this@MainActivity, null,0)

運行打印日誌如下:

結論:自定義View當在xml中使用,使用的是第二個構造方法,當在Activity中使用時,實例化時傳入幾個參數調用的就是含有幾個參數的構造方法。

實現圓形頭像的思想

我始終認爲自定義View的難度只在於它的實現思想,通常我們遇到問題的時候,並不是Google不到,而是壓根就不知道這個問題該去如何Google,如果知道了問題所產生的原因,其實問題已經迎刃而解了,最怕的是不知道問題爲什麼會產生。

實現圓形頭像的思想一個簡單的圖就可以表示了。

矩形區域是完整的圖片,圓形區域就是我們最終顯示的頭像區域,那麼就很簡單了,圓形區域與矩形區域相交,取並集區域?在矩形中畫一個與矩形長或寬相切的圓,而圓的直徑是長或寬較短的一邊。

編碼實現

獲取原有頭像的bitmap

    首先我們需要獲取設置頭像的bitmap,我們可以直接通過API來獲取設置的圖片資源,

drawable = this.getDrawable();

  再將圖片資源轉化爲bitmap

  首先我們判斷drawable是否爲空,如果爲空說明用戶沒有設置,拋出資源未找到的異常。

if (drawable == null) {
  throw new Resources.NotFoundException("Image resource not set");
}

  如果不爲空,我們創建一個與圖片資源大小相等的bitmap,並將bitmap繪製出來,代碼如下所示:

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

     通過上面的代碼,我們得到了原有的bitmap圖像,緊接着我們需要繪製圓形的bitmap,與上面類似,首先創建一個和bitmap大小一致的位圖

circleBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);

我們畫一個與bitmap等大的矩形

Paint paint = new Paint();
Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
canvas.drawRect(rect,paint);
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和canvas屬性

paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(Color.WHITE);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));

canvas.drawARGB將繪製裁剪設爲透明,paint.setXfermode中的PorterDuffXfermode類很強大,後面我們會單獨一篇文章講解。

最終我們重新將bitmap繪製出來即可

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;
}

設置最終的bitmap

    得到bitma後我們直接重新設置即可顯示

 setImageBitmap(getCircleBitmap(bitmap));

   本實例較爲簡單,就不貼所有代碼了,如有需要留言郵箱即可,如有紕漏之處,歡迎指正!晚安!

   9.15 22:17 更新

   代碼已上傳github:https://github.com/huanglinqing123/RoundImageView 

總結

以上所述是小編給大家介紹的Android自定義View之繪製圓形頭像功能,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回覆大家的。在此也非常感謝大家對神馬文庫網站的支持!
如果你覺得本文對你有幫助,歡迎轉載,煩請註明出處,謝謝!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章