android 底部圆角,android 实现部分圆角图片

需求

recyclerview 展示商品需要显示大量的图片,图片只需要顶部的角是圆角,底部的角是直角

遇到的问题

早期的时候我写过一个实现圆角的图片方式,但是有问题。滑动图片列表发现滑动卡顿,是因为我将drawable 转为Bitmap ,耗时严重 这个方法耗时有1ms~ 47ms,根据图片大小决定,所以滑动就感觉卡卡的

private Bitmap drawable2Bitmap(Drawable drawable){

//获取 Drawable 的内部宽高,包含 padding

int width = drawable.getIntrinsicWidth();

int height = drawable.getIntrinsicHeight();

//创建一个w,h的bitmap

Bitmap bitmap = Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_8888);

Canvas canvas = new Canvas(bitmap);

//设置绘画区域

drawable.setBounds(0,0,width,height);

drawable.draw(canvas);

return bitmap;

}

注意

需要跟Glide搭配使用,要使用.asBitmap().placeholder().error().into(target);

优化后的代码

public class FilletImageViewV2 extends android.support.v7.widget.AppCompatImageView {

//最后确认的宽高

private RectF drawRectF;

private Paint mPaint;

private Matrix matrix;

private BitmapShader bitmapShader;

private boolean topLeftRightCorner,bottomLeftRightCorner;//定义上面与下面的是否为圆角

private int radius = 5;

public FilletImageViewV2(Context context) {

this(context,null);

}

public FilletImageViewV2(Context context, AttributeSet attrs) {

this(context, attrs,0);

}

public FilletImageViewV2(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

init(context,attrs);

}

private void init(Context context, AttributeSet attrs){

TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.FilletImageView);

topLeftRightCorner = typedArray.getBoolean(R.styleable.FilletImageView_topLeftRightCorner,false);

bottomLeftRightCorner = typedArray.getBoolean(R.styleable.FilletImageView_bottomLeftRightCorner,false);

radius = typedArray.getInt(R.styleable.FilletImageView_filletImageRadius,5);

typedArray.recycle();

mPaint = new Paint();

mPaint.setAntiAlias(true);

matrix = new Matrix();

radius = dip2px(radius);

}

public int getRadius() {

return radius;

}

@Override

protected void onSizeChanged(int w, int h, int oldw, int oldh) {

super.onSizeChanged(w, h, oldw, oldh);

drawRectF = new RectF(0,0,w,h);

}

@Override

protected void onDraw(Canvas canvas) {

//创建一个和原图大小的图片

if (this.getDrawable() == null){

return;

}

Bitmap sourceBitMap = ((BitmapDrawable)this.getDrawable()).getBitmap();

if (sourceBitMap == null){

return;

}

//创建一个和原图大小的图片

long startTime = System.currentTimeMillis(); //起始时间

Bitmap sourceBitMap = ((BitmapDrawable)this.getDrawable()).getBitmap();

long endTime = System.currentTimeMillis(); //结束时间

long runTime = endTime - startTime;

Log.i("test", String.format("方法使用时间 %d ms", runTime));

//BitmapShader 为着色器

bitmapShader = new BitmapShader(sourceBitMap, Shader.TileMode.CLAMP,Shader.TileMode.CLAMP);

// float scaleMax = 1.0f,scaleX=1.0f,scaleY=1.0f;

float scaleMax = 1.0f;

// 如果图片的宽或者高与view的宽高不匹配,计算出需要缩放的比例;缩放后的图片的宽高,一定要大于我们view的宽高;所以我们这里取大值;

if (getWidth() != sourceBitMap.getWidth() || getHeight() !=sourceBitMap.getHeight()){

/* scaleX = (float) getWidth() / (float)sourceBitMap.getWidth();

scaleY = (float)getHeight() / (float)sourceBitMap.getHeight();*/

scaleMax = Math.max((float) getWidth() / (float)sourceBitMap.getWidth(),(float)getHeight() / (float)sourceBitMap.getHeight());

}

//对我们创建出来的bitmap进行缩放

matrix.setScale(scaleMax,scaleMax);

bitmapShader.setLocalMatrix(matrix);

mPaint.setShader(bitmapShader);

//纠正圆角

// int radius = (int) (getRadius() * scaleMax);

//画出我们需要的直角图形

canvas.drawRoundRect(drawRectF,radius,radius,mPaint);

if (topLeftRightCorner){

//左边底部

canvas.drawRect(0,canvas.getHeight() - radius ,radius,canvas.getHeight(),mPaint);

//右边底部

canvas.drawRect(canvas.getWidth() - radius, canvas.getHeight() - radius,canvas.getWidth(),canvas.getHeight(),mPaint);

}

if (bottomLeftRightCorner){

//左边顶部

canvas.drawRect(0,0,radius,radius,mPaint);

//右边顶部

canvas.drawRect(canvas.getWidth() - radius,0,canvas.getWidth(),radius,mPaint);

}

}

public int dip2px(float dipValue){

final float scale = Resources.getSystem().getDisplayMetrics().density;

return (int) (dipValue * scale + 0.5f);

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值