我正在使用来自https://github.com/hdodenhof/CircleImageView的“Circleimageview”
试图设置边界资源,它没有帮助
这是我拥有的和想要的https://docs.google.com/document/d/1VqWmaFpooYtuk7dPUAh_5-rbEzcTQTW9Jvt8QX0TNT0/edit?usp=sharing
有任何想法吗?
我正在使用来自https://github.com/hdodenhof/CircleImageView的“Circleimageview”
试图设置边界资源,它没有帮助
这是我拥有的和想要的https://docs.google.com/document/d/1VqWmaFpooYtuk7dPUAh_5-rbEzcTQTW9Jvt8QX0TNT0/edit?usp=sharing
有任何想法吗?
尝试这个 :
public class CircleImageView extends AppCompatImageView {
private static final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP;
// Default Values
private static final float DEFAULT_BORDER_WIDTH = 4;
private static final float DEFAULT_SHADOW_RADIUS = 8.0f;
// Properties
private float borderWidth;
private int canvasSize;
private float shadowRadius;
private int shadowColor = Color.BLACK;
// Object used to draw
private Bitmap image;
private Drawable drawable;
private Paint paint;
private Paint paintBorder;
private Context context;
//region Constructor & Init Method
public CircleImageView(final Context context) {
this(context, null);
}
public CircleImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CircleImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs, defStyleAttr);
}
private void init(Context context, AttributeSet attrs, int defStyleAttr) {
// Init paint
paint = new Paint();
paint.setAntiAlias(true);
paintBorder = new Paint();
paintBorder.setAntiAlias(true);
this.context = context;
// Load the styled attributes and set their properties
TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.CircularImageView, defStyleAttr, 0);
// Init Border
if (attributes.getBoolean(R.styleable.CircularImageView_civ_border, true)) {
float defaultBorderSize = DEFAULT_BORDER_WIDTH * getContext().getResources().getDisplayMetrics().density;
setBorderWidth(attributes.getDimension(R.styleable.CircularImageView_civ_border_width, defaultBorderSize));
setBorderColor(attributes.getColor(R.styleable.CircularImageView_civ_border_color, Color.WHITE));
}
// Init Shadow
if (attributes.getBoolean(R.styleable.CircularImageView_civ_shadow, false)) {
shadowRadius = DEFAULT_SHADOW_RADIUS;
drawShadow(attributes.getFloat(R.styleable.CircularImageView_civ_shadow_radius, shadowRadius), attributes.getColor(R.styleable.CircularImageView_civ_shadow_color, shadowColor));
}
}
//endregion
//region Set Attr Method
public void setBorderWidth(float borderWidth) {
this.borderWidth = borderWidth;
requestLayout();
invalidate();
}
public void setBorderColor(int borderColor) {
if (paintBorder != null)
paintBorder.setColor(borderColor);
invalidate();
}
public void addShadow() {
if (shadowRadius == 0)
shadowRadius = DEFAULT_SHADOW_RADIUS;
drawShadow(shadowRadius, shadowColor);
invalidate();
}
public void setShadowRadius(float shadowRadius) {
drawShadow(shadowRadius, shadowColor);
invalidate();
}
public void setShadowColor(int shadowColor) {
drawShadow(shadowRadius, shadowColor);
invalidate();
}
@Override
public ScaleType getScaleType() {
return SCALE_TYPE;
}
@Override
public void setScaleType(ScaleType scaleType) {
if (scaleType != SCALE_TYPE) {
throw new IllegalArgumentException(String.format("ScaleType %s not supported. ScaleType.CENTER_CROP is used by default. So you don't need to use ScaleType.", scaleType));
}
}
//endregion
//region Draw Method
@Override
public void onDraw(Canvas canvas) {
// Load the bitmap
loadBitmap();
// Check if image isn't null
if (image == null)
return;
if (!isInEditMode()) {
canvasSize = canvas.getWidth();
if (canvas.getHeight() < canvasSize) {
canvasSize = canvas.getHeight();
}
}
// circleCenter is the x or y of the view's center
// radius is the radius in pixels of the cirle to be drawn
// paint contains the shader that will texture the shape
int circleCenter = (int) (canvasSize - (borderWidth * 2)) / 2;
// Draw Border
canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, circleCenter + borderWidth - (shadowRadius + shadowRadius / 2), paintBorder);
// Draw CircularImageView
canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, circleCenter - (shadowRadius + shadowRadius / 2), paint);
}
private void loadBitmap() {
if (this.drawable == getDrawable())
return;
this.drawable = getDrawable();
this.image = drawableToBitmap(this.drawable);
updateShader();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
canvasSize = w;
if (h < canvasSize)
canvasSize = h;
if (image != null)
updateShader();
}
private void drawShadow(float shadowRadius, int shadowColor) {
this.shadowRadius = shadowRadius;
this.shadowColor = shadowColor;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
setLayerType(LAYER_TYPE_SOFTWARE, paintBorder);
}
paintBorder.setShadowLayer(shadowRadius, 0.0f, shadowRadius / 2, shadowColor);
}
private void updateShader() {
if (image == null)
return;
// Crop Center Image
image = cropBitmap(image);
// Create Shader
BitmapShader shader = new BitmapShader(image, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
// Center Image in Shader
Matrix matrix = new Matrix();
matrix.setScale((float) canvasSize / (float) image.getWidth(), (float) canvasSize / (float) image.getHeight());
shader.setLocalMatrix(matrix);
// Set Shader in Paint
paint.setShader(shader);
}
private Bitmap cropBitmap(Bitmap bitmap) {
Bitmap bmp;
if (bitmap.getWidth() >= bitmap.getHeight()) {
bmp = Bitmap.createBitmap(
bitmap,
bitmap.getWidth() / 2 - bitmap.getHeight() / 2,
0,
bitmap.getHeight(), bitmap.getHeight());
} else {
bmp = Bitmap.createBitmap(
bitmap,
0,
bitmap.getHeight() / 2 - bitmap.getWidth() / 2,
bitmap.getWidth(), bitmap.getWidth());
}
return bmp;
}
private Bitmap drawableToBitmap(Drawable drawable) {
if (drawable == null) {
return null;
} else if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable) drawable).getBitmap();
}
int intrinsicWidth = drawable.getIntrinsicWidth();
int intrinsicHeight = drawable.getIntrinsicHeight();
if (!(intrinsicWidth > 0 && intrinsicHeight > 0))
return null;
try {
// Create Bitmap object out of the drawable
Bitmap bitmap = Bitmap.createBitmap(intrinsicWidth, intrinsicHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
} catch (OutOfMemoryError e) {
// Simply return null of failed bitmap creations
Log.e(getClass().toString(), "Encountered OutOfMemoryError while generating bitmap!");
return null;
}
}
//endregion
//region Mesure Method
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = measureWidth(widthMeasureSpec);
int height = measureHeight(heightMeasureSpec);
/*int imageSize = (width < height) ? width : height;
setMeasuredDimension(imageSize, imageSize);*/
setMeasuredDimension(width, height);
}
private int measureWidth(int measureSpec) {
int result;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
// The parent has determined an exact size for the child.
result = specSize;
} else if (specMode == MeasureSpec.AT_MOST) {
// The child can be as large as it wants up to the specified size.
result = specSize;
} else {
// The parent has not imposed any constraint on the child.
result = canvasSize;
}
return result;
}
private int measureHeight(int measureSpecHeight) {
int result;
int specMode = MeasureSpec.getMode(measureSpecHeight);
int specSize = MeasureSpec.getSize(measureSpecHeight);
if (specMode == MeasureSpec.EXACTLY) {
// We were told how big to be
result = specSize;
} else if (specMode == MeasureSpec.AT_MOST) {
// The child can be as large as it wants up to the specified size.
result = specSize;
} else {
// Measure the text (beware: ascent is a negative number)
result = canvasSize;
}
return (result + 2);
}
}
现在在 XML 文件中使用这个:
<com.xyz.customclass.CircleImageView
android:id="@+id/img_event"
android:layout_width="55dp"
android:layout_height="55dp"
app:civ_border="true"
app:civ_border_color="@color/color_circular_home_image_border"
app:civ_border_width="1dp"
app:civ_shadow="true"
app:civ_shadow_color="@color/color_circular_home_image_border"
app:civ_shadow_radius="2"
app:srcCompat="@mipmap/ocassion_placeholder" />
在 attr.xml 中添加这个(创建 attr.xml :在 res ->values->attr.xml 下)
<declare-styleable name="CircularImageView">
<attr name="civ_border" format="boolean"/>
<attr name="civ_border_width" format="dimension"/>
<attr name="civ_border_color" format="color"/>
<attr name="civ_shadow" format="boolean"/>
<attr name="civ_shadow_color" format="color"/>
<attr name="civ_shadow_radius" format="float"/>
</declare-styleable>