繪製帶圓角的控件難嗎?貌似不難。對於一個普通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