同步peko:修复RectRoundImageView导致的图片加载问题

This commit is contained in:
Max
2023-12-13 15:16:17 +08:00
parent ecfe005606
commit 90a9b52551

View File

@@ -2,33 +2,24 @@ package com.chwl.app.common.widget;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.Outline;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.ImageView;
import android.view.View;
import android.view.ViewOutlineProvider;
import com.google.android.material.imageview.ShapeableImageView;
import com.google.android.material.shape.CornerFamily;
import com.google.android.material.shape.ShapeAppearanceModel;
import com.chwl.app.R;
import java.io.InputStream;
/**
* 自定义View实现圆角圆形等效果
*
* @author zhy
*/
public class RectRoundImageView extends ImageView {
public class RectRoundImageView extends ShapeableImageView {
/**
* TYPE_CIRCLE / TYPE_ROUND
@@ -37,42 +28,11 @@ public class RectRoundImageView extends ImageView {
public static final int TYPE_CIRCLE = 0;
public static final int TYPE_ROUND = 1;
/**
* 图片
*/
private Bitmap mSrc;
/**
* 圆角的大小
*/
private int mRadius = 8;
/**
* 控件的宽度
*/
private int mWidth;
/**
* 控件的高度
*/
private int mHeight;
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public int getmRadius() {
return mRadius;
}
public void setmRadius(int mRadius) {
this.mRadius = mRadius;
}
public RectRoundImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
@@ -98,17 +58,6 @@ public class RectRoundImageView extends ImageView {
for (int i = 0; i < n; i++) {
int attr = a.getIndex(i);
switch (attr) {
case R.styleable.RectRoundImageView_src:
// mSrc = BitmapFactory.decodeResource(getResources(),
// a.getResourceId(attr, 0));
InputStream is = getResources().openRawResource(a.getResourceId(attr, 0));
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inTempStorage = new byte[100 * 1024];
opts.inPreferredConfig = Config.RGB_565;
opts.inPurgeable = true;
opts.inSampleSize = 4;
mSrc = BitmapFactory.decodeStream(is, null, opts);
break;
case R.styleable.RectRoundImageView_type:
type = a.getInt(attr, 0);// 默认为Circle
break;
@@ -121,197 +70,25 @@ public class RectRoundImageView extends ImageView {
}
setScaleType(ScaleType.CENTER_CROP);
a.recycle();
setup(type, mRadius);
}
/**
* 计算控件的高度和宽度
*/
private void setup(int type, int cornerSize) {
if (type == TYPE_CIRCLE) {
setOutlineProvider(new ViewOutlineProvider() {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
Drawable drawable = getDrawable();
if (null != drawable) {
mSrc = drawableToBitmap(getDrawable());
public void getOutline(View view, Outline outline) {
int min = Math.min(view.getWidth(), view.getHeight());
int left = (view.getWidth() - min) / 2;
int top = (view.getHeight() - min) / 2;
outline.setOval(left, top, min, min);
}
/**
* 设置宽度
*/
int specMode = MeasureSpec.getMode(widthMeasureSpec);
int specSize = MeasureSpec.getSize(widthMeasureSpec);
if (specMode == MeasureSpec.EXACTLY)// match_parent , accurate
{
mWidth = specSize;
} else {
// 由图片决定的宽
int desireByImg = getPaddingLeft() + getPaddingRight()
+ mSrc.getWidth();
if (specMode == MeasureSpec.AT_MOST)// wrap_content
{
mWidth = Math.min(desireByImg, specSize);
} else
mWidth = desireByImg;
});
setClipToOutline(true);
} else if (type == TYPE_ROUND) {
setShapeAppearanceModel(ShapeAppearanceModel.builder()
.setAllCorners(CornerFamily.ROUNDED, cornerSize)
.build());
}
/***
* 设置高度
*/
specMode = MeasureSpec.getMode(heightMeasureSpec);
specSize = MeasureSpec.getSize(heightMeasureSpec);
if (specMode == MeasureSpec.EXACTLY)// match_parent , accurate
{
mHeight = specSize;
} else {
int desire = getPaddingTop() + getPaddingBottom()
+ mSrc.getHeight();
if (specMode == MeasureSpec.AT_MOST)// wrap_content
{
mHeight = Math.min(desire, specSize);
} else
mHeight = desire;
}
setMeasuredDimension(mWidth, mHeight);
}
/**
* 绘制
*/
@Override
protected void onDraw(Canvas canvas) {
switch (type) {
// 如果是TYPE_CIRCLE绘制圆形
case TYPE_CIRCLE:
int min = Math.min(mWidth, mHeight);
/**
* 长度如果不一致,按小的值进行压缩
*/
if (null != mSrc) {
mSrc = Bitmap.createScaledBitmap(mSrc, min, min, false);
canvas.drawBitmap(createCircleImage(mSrc, min), 0, 0, null);
}
break;
case TYPE_ROUND:
canvas.drawBitmap(createFramedPhoto(mWidth, mHeight, mSrc, mRadius), 0, 0, null);
break;
}
}
/**
* Drawable → Bitmap
*
* @param drawable
* @return
*/
public static Bitmap drawableToBitmap(Drawable drawable) {
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight(),
drawable.getOpacity() != PixelFormat.OPAQUE ? Config.ARGB_8888
: Config.RGB_565);
Canvas canvas = new Canvas(bitmap);
//canvas.setBitmap(bitmap);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
drawable.draw(canvas);
return bitmap;
}
/**
* 根据原图和变长绘制圆形图片
*
* @param source
* @param min
* @return
*/
private Bitmap createCircleImage(Bitmap source, int min) {
final Paint paint = new Paint();
paint.setAntiAlias(true);
Bitmap target = Bitmap.createBitmap(min, min, Config.RGB_565);
/**
* 产生一个同样大小的画布
*/
Canvas canvas = new Canvas(target);
/**
* 首先绘制圆形
*/
canvas.drawCircle(min / 2, min / 2, min / 2, paint);
/**
* 使用SRC_IN参考上面的说明
*/
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
/**
* 绘制图片
*/
canvas.drawBitmap(source, 0, 0, paint);
return target;
}
/**
* 根据原图添加圆角
*
* @param source
* @return
*/
private Bitmap createRoundConerImage(Bitmap source) {
final Paint paint = new Paint();
paint.setAntiAlias(true);
Bitmap target = Bitmap.createBitmap(mWidth, mHeight, Config.ARGB_8888);
Canvas canvas = new Canvas(target);
RectF rect = new RectF(0, 0, source.getWidth(), source.getHeight());
canvas.drawRoundRect(rect, mRadius, mRadius, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(source, 0, 0, paint);
return target;
}
/**
* @param x 图像的宽度
* @param y 图像的高度
* @param image 源图片
* @param outerRadiusRat 圆角的大小
* @return 圆角图片
*/
Bitmap createFramedPhoto(int x, int y, Bitmap image, float outerRadiusRat) {
//根据源文件新建一个darwable对象
Drawable imageDrawable = new BitmapDrawable(image);
// 新建一个新的输出图片
Bitmap output = Bitmap.createBitmap(x, y, Config.ARGB_8888);
Canvas canvas = new Canvas(output);
// 新建一个矩形
RectF outerRect = new RectF(0, 0, x, y);
// 产生一个红色的圆角矩形
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.RED);
canvas.drawRoundRect(outerRect, outerRadiusRat, outerRadiusRat, paint);
// 将源图片绘制到这个圆角矩形上
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
imageDrawable.setBounds(0, 0, x, y);
canvas.saveLayer(outerRect, paint, Canvas.ALL_SAVE_FLAG);
imageDrawable.draw(canvas);
canvas.restore();
return output;
}
}