Android 使用Universal Image Loader繪製帶圓角的圖片(一)

Android 使用Universal Image Loader繪製帶圓角的圖片(一)

  • 繪製帶圓角的控件難嗎?貌似不難。對於一個普通layout或者widget,要繪製圓角,只要把 background設置成下面這樣的drawable就好了。java

    <?xml version="1.0" encoding="utf-8"?>
      <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
      <!-- 填充的顏色 -->
      <solid android:color="@color/pure_white" />
      <!-- 設置按鈕的四個角爲弧形 -->
      <!-- android:radius 弧形的半徑 -->
      <corners android:radius="@dimen/small_corner_radius" />
      </shape>

    可是,對於圖片控件ImageView,這種方法卻會沒有效果。要想知道緣由,就得看android源碼。首先看看ImageView是如何設置Bitmap的。android

    public void setImageBitmap(Bitmap bm) {
          // if this is used frequently, may handle bitmaps explicitly
          // to reduce the intermediate drawable object
          setImageDrawable(new BitmapDrawable(mContext.getResources(), bm));
      }

    哦,它經過Bitmap建立了一個BitmapDrawable。那BitmapDrawable幹了啥呢?git

    @Override
      public void draw(Canvas canvas) {
          Bitmap bitmap = mBitmap;
          if (bitmap != null) {
              final BitmapState state = mBitmapState;
              if (state.mRebuildShader) {
                  ......
    
                  if (tmx == null && tmy == null) {
                      state.mPaint.setShader(null);
                  } else {
                      state.mPaint.setShader(new BitmapShader(bitmap,
                              tmx == null ? Shader.TileMode.CLAMP : tmx,
                              tmy == null ? Shader.TileMode.CLAMP : tmy));
                  }
                  .......
                  copyBounds(mDstRect);
              }
    
             Shader shader = state.mPaint.getShader();
              final boolean needMirroring = needMirroring();
              if (shader == null) {
                  ......
                  canvas.drawBitmap(bitmap, null, mDstRect, state.mPaint);
                  if (needMirroring) {
                      canvas.restore();
                  }
              } else {
                  ......
                  canvas.drawRect(mDstRect, state.mPaint);
              }
          }
      }

    注意紅色的代碼,能夠大概知道,這裏僅僅把圖片繪製到了一個固定的矩形框中,因此圖片部分仍是矩形。github

    那麼該如何解決這個問題呢?還好並不複雜,看看十分流行的UIL(Universal Image Loader https://github.com/nostra13/Android-Universal-Image-Loader )是怎麼作的。答案就在它的RoundedBitmapDisplayer.java中的RoundedDrawable類。canvas

    public static class RoundedDrawable extends Drawable {
    
      public RoundedDrawable(Bitmap bitmap, int cornerRadius, int margin, ViewScaleType scaleType) 
      {
          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);
          mScaleType = scaleType;
      }
    
      @Override
      public void draw(Canvas canvas)
      {
          canvas.drawRoundRect(mRect, cornerRadius, cornerRadius, paint);
          //canvas.drawRect(mDstRect, state.mPaint); ImageView的繪製方法
}
      }

    我只貼出了構造器和draw兩個方法。構造器的代碼代表它也是用BitmapShader來進行圖片的繪製的,和ImageView的區別就在於,它是用drawRoundRect的方法來進行繪製的。因此它能夠繪製出圓角的圖片。ide

Edit By MaHuaui

相關文章
相關標籤/搜索