UIL虽然提供了绘制圆角矩形的方法,但是今天遇到一个问题,我想实现只有2个圆角的圆角矩形,但是UIL的RoundedBitmapDisplayer,自动完成是四个角的圆角矩形,所以只能自己重写方法来改变RoundedBitmapDisplayer。
重新更正下,其实自定义shape完全能达到需求……like this:
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="#0099CC" /> <corners android:bottomRightRadius="0dp" android:bottomLeftRadius="0dp" android:topRightRadius="20dp" android:topLeftRadius="20dp"/> <stroke android:width="1dp" android:color="#000000"/> </shape>
下面那些又臭又长的代码就当做拓展算了……
代码如下:
public class HalfCircleImageViewDisplayer extends RoundedBitmapDisplayer { public HalfCircleImageViewDisplayer(int cornerRadiusPixels) { super(cornerRadiusPixels); } public HalfCircleImageViewDisplayer(int cornerRadiusPixels, int marginPixels) { super(cornerRadiusPixels, marginPixels); } @Override public void display(Bitmap bitmap, ImageAware imageAware, LoadedFrom loadedFrom) { if(!(imageAware instanceof ImageViewAware)) { throw new IllegalArgumentException("ImageAware should wrap ImageView. ImageViewAware is expected."); } else { imageAware.setImageDrawable(new HalfCircleImageViewDisplayer.RoundedDrawable(bitmap, this.cornerRadius, this.margin)); } } public static class RoundedDrawable extends Drawable { protected final float cornerRadius; protected final int margin; protected final RectF mRect = new RectF(); protected final RectF mBitmapRect; protected final BitmapShader bitmapShader; protected final Paint paint; protected final ShapeDrawable mDrawables; public RoundedDrawable(Bitmap bitmap, int cornerRadius, int margin) { this.cornerRadius = (float)cornerRadius; this.margin = margin; float[] outerR = new float[]{cornerRadius, cornerRadius, cornerRadius, cornerRadius, 0, 0, 0, 0}; RoundRectShape rectShape = new RoundRectShape(outerR, null, null); this.mDrawables = new ShapeDrawable(rectShape); this.bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); this.mDrawables.setBounds(margin, margin, (bitmap.getWidth() - margin), (bitmap.getHeight() - margin)); this.mBitmapRect = new RectF((float)margin, (float)margin, (float)(bitmap.getWidth() - margin), (float)(bitmap.getHeight() - margin)); this.paint = mDrawables.getPaint(); this.paint.setAntiAlias(true); this.paint.setShader(this.bitmapShader); } protected void onBoundsChange(Rect bounds) { super.onBoundsChange(bounds); this.mRect.set((float)this.margin, (float)this.margin, (float)(bounds.width() - this.margin), (float)(bounds.height() - this.margin)); Matrix shaderMatrix = new Matrix(); shaderMatrix.setRectToRect(this.mBitmapRect, this.mRect, Matrix.ScaleToFit.FILL); this.bitmapShader.setLocalMatrix(shaderMatrix); this.mDrawables.setBounds(this.margin, this.margin, (bounds.width() - this.margin), (bounds.width() - this.margin)); } public void draw(Canvas canvas) { mDrawables.draw(canvas); // canvas.drawRoundRect(this.mRect, this.cornerRadius, this.cornerRadius, this.paint); } public int getOpacity() { return -3; } public void setAlpha(int alpha) { this.paint.setAlpha(alpha); } public void setColorFilter(ColorFilter cf) { this.paint.setColorFilter(cf); } } }注意点:onBoundsChange方法中也要填入mDrawable的setBounds方法,否则Imageview中的
android:scaleType="fitXY"无效,UIL不会自动适配图片大小。
其他bug:
未知,待测试……(应该也没有,毕竟应用技术太简单了)
更好的方法:
发现其实用自定义shape就能达到上面所述效果……