同步peko:修复RectRoundImageView导致的图片加载问题
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 计算控件的高度和宽度
|
||||
*/
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
Drawable drawable = getDrawable();
|
||||
if (null != drawable) {
|
||||
mSrc = drawableToBitmap(getDrawable());
|
||||
}
|
||||
/**
|
||||
* 设置宽度
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/***
|
||||
* 设置高度
|
||||
*/
|
||||
|
||||
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);
|
||||
private void setup(int type, int cornerSize) {
|
||||
if (type == TYPE_CIRCLE) {
|
||||
setOutlineProvider(new ViewOutlineProvider() {
|
||||
@Override
|
||||
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);
|
||||
}
|
||||
break;
|
||||
case TYPE_ROUND:
|
||||
canvas.drawBitmap(createFramedPhoto(mWidth, mHeight, mSrc, mRadius), 0, 0, null);
|
||||
break;
|
||||
});
|
||||
setClipToOutline(true);
|
||||
} else if (type == TYPE_ROUND) {
|
||||
setShapeAppearanceModel(ShapeAppearanceModel.builder()
|
||||
.setAllCorners(CornerFamily.ROUNDED, cornerSize)
|
||||
.build());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user