android点击左上角划出,使用Android中的Path和RectF在左上角右上角左下角绘制圆角...

博客介绍了Android中使用Path#addRoundRect()重载方法实现圆角效果。给出了获取Path的示例方法,还展示了自定义ImageView的代码,该视图可通过XML属性设置角半径和圆角。同时建议优化onDraw()方法,在必要时构建路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有一个Path#addRoundRect()重载,它接受一个包含八个值的float数组,其中我们可以为四个角中的每一个指定x和y半径.这些值为[x,y]对,从左上角开始,顺时针绕其余部分.对于我们想要舍入的那些角,我们将该对的两个值都设置为半径值,并将它们保留为零,而不是那些.

作为一个说明性示例,一个简单的方法将返回可在您的代码段中使用的Path:

private Path getPath(float radius, boolean topLeft, boolean topRight,

boolean bottomRight, boolean bottomLeft) {

final Path path = new Path();

final float[] radii = new float[8];

if (topLeft) {

radii[0] = radius;

radii[1] = radius;

}

if (topRight) {

radii[2] = radius;

radii[3] = radius;

}

if (bottomRight) {

radii[4] = radius;

radii[5] = radius;

}

if (bottomLeft) {

radii[6] = radius;

radii[7] = radius;

}

path.addRoundRect(new RectF(0, 0, getWidth(), getHeight()),

radii, Path.Direction.CW);

return path;

}

根据您的示例说明,舍入左上角和右上角:

@Override

protected void onDraw(Canvas canvas) {

float radius = getContext().getResources().getDimension(R.dimen.round_corner_radius);

Path path = getPath(radius, true, true, false, false);

canvas.clipPath(path);

super.onDraw(canvas);

}

和往常一样,我建议尽可能地保持onDraw()方法,移动任何其他地方不必存在的东西.例如,可以在构造函数中检索radius的资源值,并将其保存在字段中.此外,只有在必要时才能构建路径;即,当视图的大小改变时,或当半径或选定的角改变时.

由于我将一个简单的自定义ImageView放在一起进行测试,我将在此处包含它,因为它演示了以上几点.此自定义视图还提供XML属性,允许在布局中设置角半径和圆角.

public class RoundishImageView extends ImageView {

public static final int CORNER_NONE = 0;

public static final int CORNER_TOP_LEFT = 1;

public static final int CORNER_TOP_RIGHT = 2;

public static final int CORNER_BOTTOM_RIGHT = 4;

public static final int CORNER_BOTTOM_LEFT = 8;

public static final int CORNER_ALL = 15;

private static final int[] CORNERS = {CORNER_TOP_LEFT,

CORNER_TOP_RIGHT,

CORNER_BOTTOM_RIGHT,

CORNER_BOTTOM_LEFT};

private final Path path = new Path();

private int cornerRadius;

private int roundedCorners;

public RoundishImageView(Context context) {

this(context, null);

}

public RoundishImageView(Context context, AttributeSet attrs) {

this(context, attrs, 0);

}

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

super(context, attrs, defStyleAttr);

TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundishImageView);

cornerRadius = a.getDimensionPixelSize(R.styleable.RoundishImageView_cornerRadius, 0);

roundedCorners = a.getInt(R.styleable.RoundishImageView_roundedCorners, CORNER_NONE);

a.recycle();

}

public void setCornerRadius(int radius) {

if (cornerRadius != radius) {

cornerRadius = radius;

setPath();

invalidate();

}

}

public int getCornerRadius() {

return cornerRadius;

}

public void setRoundedCorners(int corners) {

if (roundedCorners != corners) {

roundedCorners = corners;

setPath();

invalidate();

}

}

public boolean isCornerRounded(int corner) {

return (roundedCorners & corner) == corner;

}

@Override

protected void onDraw(Canvas canvas) {

if (!path.isEmpty()) {

canvas.clipPath(path);

}

super.onDraw(canvas);

}

@Override

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

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

setPath();

}

private void setPath() {

path.rewind();

if (cornerRadius >= 1f && roundedCorners != CORNER_NONE) {

final float[] radii = new float[8];

for (int i = 0; i < 4; i++) {

if (isCornerRounded(CORNERS[i])) {

radii[2 * i] = cornerRadius;

radii[2 * i + 1] = cornerRadius;

}

}

path.addRoundRect(new RectF(0, 0, getWidth(), getHeight()),

radii, Path.Direction.CW);

}

}

}

要使XML属性起作用,需要在< resources>中进行以下操作,您可以将此文件放在项目的res / values /文件夹中,或添加到可能已存在的文件中.

attrs.xml

cornerRadius是一个维度属性,应指定为dp或px值. roundedCorners是一个标志属性,可以使用竖线字符|来选择多个角.例如:

xmlns:app="http://schemas.android.com/apk/res-auto"

android:id="@+id/riv"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:adjustViewBounds="true"

android:scaleType="fitXY"

android:src="@drawable/magritte"

app:cornerRadius="@dimen/round_corner_radius"

app:roundedCorners="topLeft|topRight" />

97cd7f386b8a3075cbc7c5dd6d79ace3.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值