Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android中實現圓角圖片的幾種方法

Android中實現圓角圖片的幾種方法

編輯:關於Android編程

Android中實現圓角圖片有多種姿勢,不知你解鎖了幾種?

方法一:setXfermode法

此種方式就是再new一個相同尺寸的bitmap,然後使用paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));先畫圓角矩形,再畫原始bitmap,然後就得到了一個圓角的bitmap了。

public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, float roundPx) {

  Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);
  Canvas canvas = new Canvas(output);

  final int color = 0xff424242;
  final Paint paint = new Paint();
  final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
  final RectF rectF = new RectF(rect);

  paint.setAntiAlias(true);
  canvas.drawARGB(0, 0, 0, 0);
  paint.setColor(color);
  canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

  paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
  canvas.drawBitmap(bitmap, rect, rect, paint);

  return output;
}

點評:

早期用得較多,占用bitmap雙倍內存。

方法二:使用BitmapShader

此種方式是先將bitmap生成BitmapShader,然後將其繪制到canvas中, 部分關鍵代碼如下,完整代碼請參考QuickAF中的RoundImageView

bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
paint.setShader(bitmapShader);
@Override
public void draw(Canvas canvas) {
  Rect bounds = getBounds();
  canvas.drawRoundRect(fillRect, radius, radius, paint);
  if (mBorderWidth > 0) {
    if (mIsCircle) {
      canvas.drawCircle(bounds.width() / 2, bounds.height() / 2, radius, strokePaint);
    }
    else {
      canvas.drawRoundRect(fillRect, radius, radius, strokePaint);
    }
  }
}

點評:

占用內存較大,實現有點小復雜。

方法三:圖片加載庫

目前github上有許多流行的圖片加載庫,基於上都附帶圓角圖片功能,只需要稍微配置一下,即可輕松的實現想要的效果。其實在底層,無非也是使用上面的兩種方式。比如Android-Universal-Image-Loader 早期的RoundedBitmapDisplayer使用setXfermode來實現,後來使用BitmapShader實現。

DisplayImageOptions options = new DisplayImageOptions.Builder()
    .displayer(new RoundedBitmapDisplayer()) // display rounded bitmap
    .build();

再以比較另類的fresco為例,雖然底層是以C實現,不過在圓角處理上,仍然還是在Java層實現,用的方式還是BitmapShader。不過對於非bitmap的圓角實現,fresco是用Paint直接畫的。附上fresco配置。

<com.facebook.drawee.view.SimpleDraweeView
 android:id="@+id/my_image_view"
 android:layout_width="20dp"
 android:layout_height="20dp"
 fresco:fadeDuration="300"
 fresco:actualImageScaleType="focusCrop"
 fresco:placeholderImage="@color/wait_color"
 fresco:placeholderImageScaleType="fitCenter"
 fresco:failureImage="@drawable/error"
 fresco:failureImageScaleType="centerInside"
 fresco:retryImage="@drawable/retrying"
 fresco:retryImageScaleType="centerCrop"
 fresco:progressBarImage="@drawable/progress_bar"
 fresco:progressBarImageScaleType="centerInside"
 fresco:progressBarAutoRotateInterval="1000"
 fresco:backgroundImage="@color/blue"
 fresco:overlayImage="@drawable/watermark"
 fresco:pressedStateOverlayImage="@color/red"
 fresco:roundAsCircle="false"
 fresco:roundedCornerRadius="1dp"
 fresco:roundTopLeft="true"
 fresco:roundTopRight="false"
 fresco:roundBottomLeft="false"
 fresco:roundBottomRight="true"
 fresco:roundWithOverlayColor="@color/corner_color"
 fresco:roundingBorderWidth="2dp"
 fresco:roundingBorderColor="@color/border_color"
/>

點評:

由框架實現,使用簡單,穩定。

方法四:遮罩

此種方式還是使用setXfermode,不過與方法一不同的是:不對圖片作任何更改,只在圓角之外再畫一層與背景顏色相同的四個角來遮擋,在視覺上造成圓角圖片的效果。關鍵代碼如下:

@Override
protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);
  if (src != null && dst != null) {
    int w = getMeasuredWidth(), h = getMeasuredHeight();
    int sc = canvas.saveLayer(0, 0, w, h, null,
      Canvas.MATRIX_SAVE_FLAG | Canvas.CLIP_SAVE_FLAG | Canvas.HAS_ALPHA_LAYER_SAVE_FLAG
        | Canvas.FULL_COLOR_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG);
    canvas.drawBitmap(dst, 0, 0, paint); // 圓角矩形
    paint.setXfermode(mode); // new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT);
    canvas.drawBitmap(src, 0, 0, paint); // 長方形
    paint.setXfermode(null);
    canvas.restoreToCount(sc);
  }
}

詳細代碼請參考QuickAF中的RoundMaskView

使用這種方式,圓角化的對象不限於ImageView,還可以是任意的layout哦,比如下面的示例

<FrameLayout
  android:layout_width="match_parent"
  android:layout_height="wrap_content">

  <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <ImageView
      android:layout_width="match_parent"
      android:layout_height="150dp"
      android:src="@color/colorAccent"/>

    <TextView
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:layout_gravity="bottom"
      android:background="@color/black_alpha_50"
      android:padding="12dp"
      android:text="I am text"/>
  </LinearLayout>

  <cn.ieclipse.af.view.RoundMaskView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:radius="10dp"
    app:af_borderColor="@color/white"
    app:af_borderWidth="1dp"/>
</FrameLayout>

配合FrameLayout,將LinearLayout實現了圓角,在視覺效果上,ImageView左上和右上圓角,TextView左下和右下圓角。

點評:

具有一定的局限性,不過不限於圖片,所有的Layout都可以在視覺上實現圓角。

關於

QuickAF是一個Android平台上的app快速開發框架。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持本站。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved