如何为可绘制的线条形状制作圆角破折号或圆点
How to make a rounded dashes or dots for line drawable shape
有什么方法可以让 cap/dot 像附图中那样变圆吗?
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="line">
<stroke
android:width="2dp"
android:color="@color/grey"
android:dashWidth="3dp"
android:dashGap="3dp" />
</shape>
注意
伙计们,我知道如何制作虚线,我想问一下如何制作 "rounded" 破折号。!!看看这张来自 Adobe XD 的图片就知道我的意思了..!
您可以使用自定义视图并在 canvas 上绘图来实现目标。请尝试此操作并根据您的需要调整 sizes/styling:
public class RoundedDashView extends View {
public enum Orientation {
VERTICAL,
HORIZONTAL
}
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Path path = new Path();
private Orientation orientation = Orientation.HORIZONTAL;
public RoundedDashView(Context context) {
super(context);
init();
}
public RoundedDashView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public RoundedDashView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public RoundedDashView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
private void init() {
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStrokeWidth(10);
paint.setColor(Color.GRAY);
paint.setPathEffect(new DashPathEffect(new float[]{20, 25}, 20));
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
path.reset();
if (orientation == Orientation.VERTICAL) {
path.moveTo(getWidth() / 2, 0);
path.quadTo(getWidth() / 2, getHeight() / 2, getWidth() / 2, getHeight());
} else {
path.moveTo(0, getHeight() / 2);
path.quadTo(getWidth() / 2, getHeight() / 2, getWidth(), getHeight() / 2);
}
canvas.drawPath(path, paint);
}
public void setOrientation(Orientation orientation) {
this.orientation = orientation;
invalidate();
}
}
我使用了上面的答案并对其进行了修改,使其可以在 xml 中进行配置。复制 java class:
public class RoundedDashView extends View {
private static final int HORIZONTAL = 0;
private static final int VERTICAL = 1;
private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Path path = new Path();
private float gap = 6f;
private float width = 8f;
private int orientation = HORIZONTAL;
private int color = getResources().getColor(R.color.dot_inactive);
public RoundedDashView(Context context) {
super(context);
init();
}
public RoundedDashView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public RoundedDashView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundedDashView, defStyleAttr, R.style.RoundedDasViewDefault);
orientation = a.getInt(R.styleable.RoundedDashView_orientation, VERTICAL);
color = a.getColor(R.styleable.RoundedDashView_dividerDashColor, color);
gap = a.getFloat(R.styleable.RoundedDashView_dividerDashGap, gap);
width = a.getFloat(R.styleable.RoundedDashView_dividerDashWidth, width);
init();
a.recycle();
}
public void init() {
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStrokeWidth(gap);
paint.setColor(color);
paint.setPathEffect(new DashPathEffect(new float[]{gap, width}, gap));
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
path.reset();
applyOrientation();
canvas.drawPath(path, paint);
}
public void setOrientation(int orientation) {
this.orientation = orientation;
applyOrientation();
invalidate();
}
public void applyOrientation() {
if (orientation == VERTICAL) {
path.moveTo((float) getWidth() / 2, 0);
path.quadTo((float) getWidth() / 2, (float) getHeight() / 2, (float) getWidth() / 2, getHeight());
} else if (orientation == HORIZONTAL) {
path.moveTo(0, (float) getHeight() / 2);
path.quadTo((float) getWidth() / 2, (float) getHeight() / 2, getWidth(), (float) getHeight() / 2);
}
}
public void setColor(int color) {
this.color = color;
paint.setColor(color);
invalidate();
}
public int getColor() {
return color;
}
}
在/res目录下创建一个attr文件并添加这个
<declare-styleable name="RoundedDashView">
<attr name="dividerDashGap" format="float" />
<attr name="dividerDashWidth" format="float" />
<attr name="dividerDashColor" format="reference|color" />
<attr name="orientation" format="enum">
<enum name="vertical" value="1" />
<enum name="horizontal" value="0" />
</attr>
</declare-styleable>
向样式文件添加样式
<style name="RoundedDasViewDefault">
<item name="dividerDashGap">6</item>
<item name="dividerDashWidth">8</item>
<item name="dividerDashColor">@color/dot_inactive</item>
<item name="orientation">horizontal</item>
</style>
在 XML
中设置属性
<com.neon.robinfood.utils.RoundedDashView
android:layout_width="6dp"
android:layout_marginStart="8dp"
android:layout_height="@dimen/dimen_36dp"
app:dividerDashGap="6"
app:dividerDashWidth="8"
app:dividerDashColor="@color/red"
app:orientation="vertical"/>
有什么方法可以让 cap/dot 像附图中那样变圆吗?
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="line">
<stroke
android:width="2dp"
android:color="@color/grey"
android:dashWidth="3dp"
android:dashGap="3dp" />
</shape>
注意
伙计们,我知道如何制作虚线,我想问一下如何制作 "rounded" 破折号。!!看看这张来自 Adobe XD 的图片就知道我的意思了..!
您可以使用自定义视图并在 canvas 上绘图来实现目标。请尝试此操作并根据您的需要调整 sizes/styling:
public class RoundedDashView extends View {
public enum Orientation {
VERTICAL,
HORIZONTAL
}
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Path path = new Path();
private Orientation orientation = Orientation.HORIZONTAL;
public RoundedDashView(Context context) {
super(context);
init();
}
public RoundedDashView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public RoundedDashView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public RoundedDashView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
private void init() {
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStrokeWidth(10);
paint.setColor(Color.GRAY);
paint.setPathEffect(new DashPathEffect(new float[]{20, 25}, 20));
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
path.reset();
if (orientation == Orientation.VERTICAL) {
path.moveTo(getWidth() / 2, 0);
path.quadTo(getWidth() / 2, getHeight() / 2, getWidth() / 2, getHeight());
} else {
path.moveTo(0, getHeight() / 2);
path.quadTo(getWidth() / 2, getHeight() / 2, getWidth(), getHeight() / 2);
}
canvas.drawPath(path, paint);
}
public void setOrientation(Orientation orientation) {
this.orientation = orientation;
invalidate();
}
}
我使用了上面的答案并对其进行了修改,使其可以在 xml 中进行配置。复制 java class:
public class RoundedDashView extends View {
private static final int HORIZONTAL = 0;
private static final int VERTICAL = 1;
private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Path path = new Path();
private float gap = 6f;
private float width = 8f;
private int orientation = HORIZONTAL;
private int color = getResources().getColor(R.color.dot_inactive);
public RoundedDashView(Context context) {
super(context);
init();
}
public RoundedDashView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public RoundedDashView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundedDashView, defStyleAttr, R.style.RoundedDasViewDefault);
orientation = a.getInt(R.styleable.RoundedDashView_orientation, VERTICAL);
color = a.getColor(R.styleable.RoundedDashView_dividerDashColor, color);
gap = a.getFloat(R.styleable.RoundedDashView_dividerDashGap, gap);
width = a.getFloat(R.styleable.RoundedDashView_dividerDashWidth, width);
init();
a.recycle();
}
public void init() {
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStrokeWidth(gap);
paint.setColor(color);
paint.setPathEffect(new DashPathEffect(new float[]{gap, width}, gap));
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
path.reset();
applyOrientation();
canvas.drawPath(path, paint);
}
public void setOrientation(int orientation) {
this.orientation = orientation;
applyOrientation();
invalidate();
}
public void applyOrientation() {
if (orientation == VERTICAL) {
path.moveTo((float) getWidth() / 2, 0);
path.quadTo((float) getWidth() / 2, (float) getHeight() / 2, (float) getWidth() / 2, getHeight());
} else if (orientation == HORIZONTAL) {
path.moveTo(0, (float) getHeight() / 2);
path.quadTo((float) getWidth() / 2, (float) getHeight() / 2, getWidth(), (float) getHeight() / 2);
}
}
public void setColor(int color) {
this.color = color;
paint.setColor(color);
invalidate();
}
public int getColor() {
return color;
}
}
在/res目录下创建一个attr文件并添加这个
<declare-styleable name="RoundedDashView">
<attr name="dividerDashGap" format="float" />
<attr name="dividerDashWidth" format="float" />
<attr name="dividerDashColor" format="reference|color" />
<attr name="orientation" format="enum">
<enum name="vertical" value="1" />
<enum name="horizontal" value="0" />
</attr>
</declare-styleable>
向样式文件添加样式
<style name="RoundedDasViewDefault">
<item name="dividerDashGap">6</item>
<item name="dividerDashWidth">8</item>
<item name="dividerDashColor">@color/dot_inactive</item>
<item name="orientation">horizontal</item>
</style>
在 XML
中设置属性<com.neon.robinfood.utils.RoundedDashView
android:layout_width="6dp"
android:layout_marginStart="8dp"
android:layout_height="@dimen/dimen_36dp"
app:dividerDashGap="6"
app:dividerDashWidth="8"
app:dividerDashColor="@color/red"
app:orientation="vertical"/>