Is it difficult to draw a control with rounded corners? It seems not difficult. For a normal layout or widget, to draw the fillet, just set the background to the following drawable on the line.
<?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>
However, for a picture control ImageView, this method has no effect. To know why, you have to look at the Android source code. First look at how ImageView is set up for bitmap.
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)); }
Oh, it creates a bitmapdrawable through bitmap. What did the Bitmapdrawable do?
@Override public void Draw (canvas canvas) {Bitmap Bitmap = Mbitmap; if (bitmap! = null) {final bitmapstate state = Mbitmapstate; if (State.mrebuildshader) {... if (TMX = = NULL && tmy = = null) {St Ate.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); } } }
Note The red code, you can probably know, here just to draw the picture into a fixed rectangular box, so the picture part is still a rectangle.
So how do we solve this problem? Fortunately it is not complicated to see how popular UIL (Universal Image Loader https://github.com/nostra13/Android-Universal-Image-Loader) is doing. The answer is in the Roundeddrawable class in its roundedbitmapdisplayer.java.
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的绘制方法?} }
I only posted the constructor and draw two methods. The code of the constructor indicates that it is also used Bitmapshader to draw the picture, and the difference between the ImageView is that it is drawn using the Drawroundrect method. So it can draw a picture with rounded corners.