如何将图像视图转换成不同的形状?
How to covert imageview into different shape?
其实我想把图片转换成图中提到的形状。我在 SO
中尝试了很多类似的问题,但其中 none 很有帮助。您可能建议在 imageView
的前景中使用 drawable,但我必须以编程方式设置前景,这仅对 api>23 有效。谁能帮我解决这个问题?
您可以在图像中看到图像的背景。我想以编程方式将图像转换成那个形状。
即使我尝试使用 Gradient Drawable
但它是徒劳的
代码:
GradientDrawable gradientDrawable= new GradientDrawable();
float[] radii = new float[8];
radii[0] = 15; // Goes clockwise, so this is the top left corner start position.
radii[1] = 15; // top left end position.
radii[2] = 15;
radii[3] = 15;
radii[4]=0;
radii[5]=0;
radii[6] = 15;
radii[7] = 15;
gradientDrawable.setCornerRadii(radii);
holder.img.setBackgroundDrawable(gradientDrawable);
您可以通过应用 clipPath 更改 imageView class 的 onDraw
方法:
@Override
protected void onDraw(Canvas canvas) {
float[] radii = new float[8];
radii[0] = radius; // Goes clockwise, so this is the top left corner start position.
radii[1] = radius; // top left end position.
radii[2] = radius;
radii[3] = radius;
// Skipping 4 and 5 because thats the bottom right corner.
radii[6] = radius;
radii[7] = radius;
Path clipPath = new Path();
clipPath.addRoundRect(new RectF(0, 0, this.getWidth(), this.getHeight()), radii, Path.Direction.CW);
canvas.clipPath(clipPath);
super.onDraw(canvas);
}
参考文献:
如果你想创建一个可绘制的图像,那么你可以为不同的角设置不同的半径,比如
<corners
android:topRightRadius="15dp"
android:topLeftRadius="15dp"
android:bottomLeftRadius="15dp"/>
除此之外,您还可以使用
GradientDrawable 创建背景图像并使用 setCornerRadii
可变角半径。
GradientDrawable 示例
GradientDrawable gradientDrawable= new GradientDrawable();
gradientDrawable.setCornerRadii(15,15,15,15,15,15,0,0);
void setCornerRadii (float[] radii)
Specifies radii for each of the 4 corners. For each corner, the array
contains 2 values, [X_radius, Y_radius]. The corners are ordered
top-left, top-right, bottom-right, bottom-left. This property is
honored only when the shape is of type RECTANGLE.
设置颜色使用 gradientDrawable.setColor(YOUR_COLOR)
方法,您可以在那里使用多种颜色进行渐变外观。
此处 (15,15,15,15,15,15,0,0) 建议从左上角开始的所有 4 个角的 X 半径和 Y 半径。
最后我参考了from this and
解决了我的问题
最后 ImageView Class 看起来像:
public class RoundedImageView extends ImageView {
private Path mMaskPath;
private Paint mMaskPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private int mCornerRadius = 10;
public RoundedImageView(Context context) {
super(context);
init();
}
public RoundedImageView(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
init();
}
public RoundedImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
ViewCompat.setLayerType(this, ViewCompat.LAYER_TYPE_SOFTWARE, null);
mMaskPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
}
public void setCornerRadius(int cornerRadius) {
mCornerRadius = cornerRadius;
generateMaskPath(getWidth(), getHeight());
invalidate();
}
@Override
protected void onSizeChanged(int w, int h, int oldW, int oldH) {
super.onSizeChanged(w, h, oldW, oldH);
if (w != oldW || h != oldH) {
generateMaskPath(w, h);
}
}
private void generateMaskPath(int w, int h) {
mMaskPath = new Path();
float[] radii = new float[8];
radii[0] = 20; // Goes clockwise, so this is the top left corner start position.
radii[1] = 20; // top left end position.
radii[2] = 20;
radii[3] = 20;
// Skipping 4 and 5 because thats the bottom right corner.
radii[6] = 20;
radii[7] = 20;
mMaskPath.addRoundRect(new RectF(0,0,w,h), radii, Path.Direction.CW);
mMaskPath.setFillType(Path.FillType.INVERSE_WINDING);
}
@SuppressLint("WrongConstant")
@Override
protected void onDraw(Canvas canvas) {
if(canvas.isOpaque()) { // If canvas is opaque, make it transparent
canvas.saveLayerAlpha(0, 0, canvas.getWidth(), canvas.getHeight(), 255, Canvas.HAS_ALPHA_LAYER_SAVE_FLAG);
}
super.onDraw(canvas);
if(mMaskPath != null) {
canvas.drawPath(mMaskPath, mMaskPaint);
}
}
}
其实我想把图片转换成图中提到的形状。我在 SO
中尝试了很多类似的问题,但其中 none 很有帮助。您可能建议在 imageView
的前景中使用 drawable,但我必须以编程方式设置前景,这仅对 api>23 有效。谁能帮我解决这个问题?
您可以在图像中看到图像的背景。我想以编程方式将图像转换成那个形状。
即使我尝试使用 Gradient Drawable
但它是徒劳的
代码:
GradientDrawable gradientDrawable= new GradientDrawable();
float[] radii = new float[8];
radii[0] = 15; // Goes clockwise, so this is the top left corner start position.
radii[1] = 15; // top left end position.
radii[2] = 15;
radii[3] = 15;
radii[4]=0;
radii[5]=0;
radii[6] = 15;
radii[7] = 15;
gradientDrawable.setCornerRadii(radii);
holder.img.setBackgroundDrawable(gradientDrawable);
您可以通过应用 clipPath 更改 imageView class 的 onDraw
方法:
@Override
protected void onDraw(Canvas canvas) {
float[] radii = new float[8];
radii[0] = radius; // Goes clockwise, so this is the top left corner start position.
radii[1] = radius; // top left end position.
radii[2] = radius;
radii[3] = radius;
// Skipping 4 and 5 because thats the bottom right corner.
radii[6] = radius;
radii[7] = radius;
Path clipPath = new Path();
clipPath.addRoundRect(new RectF(0, 0, this.getWidth(), this.getHeight()), radii, Path.Direction.CW);
canvas.clipPath(clipPath);
super.onDraw(canvas);
}
参考文献:
如果你想创建一个可绘制的图像,那么你可以为不同的角设置不同的半径,比如
<corners
android:topRightRadius="15dp"
android:topLeftRadius="15dp"
android:bottomLeftRadius="15dp"/>
除此之外,您还可以使用
GradientDrawable 创建背景图像并使用 setCornerRadii
可变角半径。
GradientDrawable 示例
GradientDrawable gradientDrawable= new GradientDrawable();
gradientDrawable.setCornerRadii(15,15,15,15,15,15,0,0);
void setCornerRadii (float[] radii)
Specifies radii for each of the 4 corners. For each corner, the array contains 2 values, [X_radius, Y_radius]. The corners are ordered top-left, top-right, bottom-right, bottom-left. This property is honored only when the shape is of type RECTANGLE.
设置颜色使用 gradientDrawable.setColor(YOUR_COLOR)
方法,您可以在那里使用多种颜色进行渐变外观。
此处 (15,15,15,15,15,15,0,0) 建议从左上角开始的所有 4 个角的 X 半径和 Y 半径。
最后我参考了from this and
最后 ImageView Class 看起来像:
public class RoundedImageView extends ImageView {
private Path mMaskPath;
private Paint mMaskPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private int mCornerRadius = 10;
public RoundedImageView(Context context) {
super(context);
init();
}
public RoundedImageView(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
init();
}
public RoundedImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
ViewCompat.setLayerType(this, ViewCompat.LAYER_TYPE_SOFTWARE, null);
mMaskPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
}
public void setCornerRadius(int cornerRadius) {
mCornerRadius = cornerRadius;
generateMaskPath(getWidth(), getHeight());
invalidate();
}
@Override
protected void onSizeChanged(int w, int h, int oldW, int oldH) {
super.onSizeChanged(w, h, oldW, oldH);
if (w != oldW || h != oldH) {
generateMaskPath(w, h);
}
}
private void generateMaskPath(int w, int h) {
mMaskPath = new Path();
float[] radii = new float[8];
radii[0] = 20; // Goes clockwise, so this is the top left corner start position.
radii[1] = 20; // top left end position.
radii[2] = 20;
radii[3] = 20;
// Skipping 4 and 5 because thats the bottom right corner.
radii[6] = 20;
radii[7] = 20;
mMaskPath.addRoundRect(new RectF(0,0,w,h), radii, Path.Direction.CW);
mMaskPath.setFillType(Path.FillType.INVERSE_WINDING);
}
@SuppressLint("WrongConstant")
@Override
protected void onDraw(Canvas canvas) {
if(canvas.isOpaque()) { // If canvas is opaque, make it transparent
canvas.saveLayerAlpha(0, 0, canvas.getWidth(), canvas.getHeight(), 255, Canvas.HAS_ALPHA_LAYER_SAVE_FLAG);
}
super.onDraw(canvas);
if(mMaskPath != null) {
canvas.drawPath(mMaskPath, mMaskPaint);
}
}
}