在drawable上绘制路径并将drawable设置为View / ImageView的背景或src时出现问题。似乎正在发生的事情是,我做箭头的一侧的路径总是比直线稍厚......我正在测试具有固定尺寸的视图。任何人都有关于我如何解决它的想法?
这是我的可绘制代码。
public class ArrowDrawable extends Drawable {
public static final String TAG = ArrowDrawable.class.getSimpleName();
private Paint outlinePaint;
private Paint fillPaint;
int padding = 40;
int arrowPosition = 50;
int arrowHeight = 60;
int strokeWidth = 10;
Path path = new Path();
public enum Direction {
RIGHT,
LEFT;
}
Direction direction = Direction.RIGHT;
public ArrowDrawable() {
init();
}
private void init() {
outlinePaint = new Paint();
outlinePaint.setStyle(Paint.Style.STROKE); // set to STOKE
outlinePaint.setStrokeJoin(Paint.Join.BEVEL); // set the join to round you want
outlinePaint.setStrokeCap(Paint.Cap.ROUND); // set the outlinePaint cap to round too
outlinePaint.setPathEffect(new CornerPathEffect(2)); // set the path effect when they join.
outlinePaint.setAntiAlias(true);
outlinePaint.setStrokeWidth(strokeWidth);
fillPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
fillPaint.setStrokeWidth(strokeWidth);
fillPaint.setStrokeJoin(Paint.Join.ROUND);
fillPaint.setPathEffect(new CornerPathEffect(2));
fillPaint.setStyle(Paint.Style.FILL);
fillPaint.setAntiAlias(true);
fillPaint.setColor(Color.WHITE);
}
public void setDirection(Direction direction) {
this.direction = direction;
invalidateSelf();
}
public void setStrokeColor(int color) {
outlinePaint.setColor(color);
invalidateSelf();
}
public void setFillColor(int color) {
fillPaint.setColor(color);
invalidateSelf();
}
public void setPadding(int padding) {
this.padding = padding;
invalidateSelf();
}
public void setArrowPosition(int arrowPosition) {
this.arrowPosition = arrowPosition;
invalidateSelf();
}
public void setArrowHeight(int arrowHeight) {
this.arrowHeight = arrowHeight;
invalidateSelf();
}
public void setStrokeWidth(int strokeWidth) {
this.strokeWidth = strokeWidth;
invalidateSelf();
}
@Override
public void draw(Canvas canvas) {
final Rect bounds = getBounds();
Log.d(TAG, "draw: " + canvas.getWidth() + " " + canvas.getHeight());
Path path;
if (direction == Direction.RIGHT) {
path = pointRight(bounds);
} else if (direction == Direction.LEFT) {
path = pointLeft(bounds);
} else {
throw new IllegalArgumentException("Direction is not supported");
}
path.computeBounds(new RectF(bounds), false);
canvas.drawPath(path, outlinePaint);
}
@Override
public void invalidateSelf() {
path = null;
super.invalidateSelf();
}
@Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
invalidateSelf();
}
public Path pointRight(Rect bounds) {
if (path != null) {
return path;
}
final Rect newRect = new Rect(bounds.left, bounds.top, bounds.right - padding - strokeWidth, bounds.bottom);
path = new Path();
path.moveTo(newRect.left, newRect.top);
path.lineTo(newRect.right, newRect.top);
path.lineTo(newRect.right, newRect.top + arrowPosition);
path.lineTo(bounds.right - strokeWidth, newRect.top + arrowPosition + arrowHeight / 2.0f);
path.lineTo(newRect.right, newRect.top + arrowPosition + arrowHeight);
path.lineTo(newRect.right, newRect.bottom);
path.lineTo(newRect.left, newRect.bottom);
path.close();
return path;
}
public Path pointLeft(Rect bounds) {
if (path != null) {
return path;
}
final Rect newRect = new Rect(bounds.left + padding + strokeWidth, bounds.top, bounds.right, bounds.bottom);
path = new Path();
path.moveTo(newRect.left, newRect.top);
path.lineTo(newRect.left, newRect.top + arrowPosition);
path.lineTo(bounds.left + strokeWidth, newRect.top + arrowPosition + arrowHeight / 2.0f);
path.lineTo(newRect.left, newRect.top + arrowPosition + arrowHeight);
path.lineTo(newRect.left, newRect.bottom);
path.lineTo(newRect.right, newRect.bottom);
path.lineTo(newRect.right, newRect.top);
path.close();
return path;
}
@Override
public void setAlpha(int alpha) {
}
@Override
public void setColorFilter(ColorFilter colorFilter) {
}
@Override
public int getOpacity() {
return PixelFormat.UNKNOWN;
}
}
答案 0 :(得分:0)
所以我使用以下可绘制代码完成了这项工作。 然而,这会将箭头绘制在边界之外。我故意这样做,所以我不必添加填充到我把它作为背景的视图。我只需要在视图的父容器上设置一些标志,以便不剪切背景。
android:clipChildren="false"
android:clipToPadding="false"
现在,左箭头和右箭头可绘制似乎正常。
public class ArrowDrawable extends Drawable {
public static final String TAG = ArrowDrawable.class.getSimpleName();
private Paint outlinePaint;
private Paint fillPaint;
private int padding = 40;
private int arrowPosition = 50;
private int arrowHeight = 60;
private int strokeWidth = 4;
Path path;
public enum Direction {
RIGHT,
LEFT
}
Direction direction = Direction.RIGHT;
public ArrowDrawable() {
init();
}
private void init() {
outlinePaint = new Paint();
outlinePaint.setDither(true); // set the dither to true
outlinePaint.setStyle(Paint.Style.STROKE); // set to STOKE
outlinePaint.setStrokeJoin(Paint.Join.ROUND); // set the join to round you want
outlinePaint.setStrokeCap(Paint.Cap.ROUND); // set the outlinePaint cap to round too
outlinePaint.setPathEffect(new CornerPathEffect(2)); // set the path effect when they join.
outlinePaint.setAntiAlias(true);
fillPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
fillPaint.setStrokeJoin(Paint.Join.ROUND);
fillPaint.setPathEffect(new CornerPathEffect(2));
fillPaint.setStyle(Paint.Style.FILL);
fillPaint.setAntiAlias(true);
fillPaint.setColor(Color.TRANSPARENT);
}
public void setDirection(Direction direction) {
this.direction = direction;
invalidateSelf();
}
public void setStrokeColor(int color) {
outlinePaint.setColor(color);
invalidateSelf();
}
public void setFillColor(int color) {
fillPaint.setColor(color);
invalidateSelf();
}
public void setPadding(int padding) {
this.padding = padding;
invalidateSelf();
}
public void setArrowPosition(int arrowPosition) {
this.arrowPosition = arrowPosition;
invalidateSelf();
}
public void setArrowHeight(int arrowHeight) {
this.arrowHeight = arrowHeight;
invalidateSelf();
}
public void setStrokeWidth(int strokeWidth) {
this.strokeWidth = strokeWidth;
invalidateSelf();
}
@Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
recalculatePath(bounds);
}
private void recalculatePath(Rect bounds) {
if (direction == Direction.RIGHT) {
path = pointRight(bounds);
} else if (direction == Direction.LEFT) {
path = pointLeft(bounds);
} else {
throw new IllegalArgumentException("Direction is not supported");
}
}
@Override
public void draw(Canvas canvas) {
if (path == null) {
return;
}
outlinePaint.setStrokeWidth(strokeWidth);
fillPaint.setStrokeWidth(strokeWidth);
canvas.drawPath(path, fillPaint);
canvas.drawPath(path, outlinePaint);
}
@Override
public void invalidateSelf() {
recalculatePath(getBounds());
super.invalidateSelf();
}
public Path pointRight(Rect bounds) {
final Rect newRect = new Rect(bounds.left, bounds.top, bounds.right, bounds.bottom);
path = new Path();
path.moveTo(newRect.left, newRect.top);
path.lineTo(newRect.right, newRect.top);
path.lineTo(newRect.right, newRect.top + arrowPosition);
path.lineTo(bounds.right + padding - strokeWidth, newRect.top + arrowPosition + arrowHeight / 2.0f);
path.lineTo(newRect.right, newRect.top + arrowPosition + arrowHeight);
path.lineTo(newRect.right, newRect.bottom);
path.lineTo(newRect.left, newRect.bottom);
path.close();
return path;
}
public Path pointLeft(Rect bounds) {
final Rect newRect = new Rect(bounds.left, bounds.top, bounds.right, bounds.bottom);
path = new Path();
path.moveTo(newRect.left, newRect.top);
path.lineTo(newRect.left, newRect.top + arrowPosition);
path.lineTo(bounds.left - padding + strokeWidth, newRect.top + arrowPosition + arrowHeight / 2.0f);
path.lineTo(newRect.left, newRect.top + arrowPosition + arrowHeight);
path.lineTo(newRect.left, newRect.bottom);
path.lineTo(newRect.right, newRect.bottom);
path.lineTo(newRect.right, newRect.top);
path.close();
return path;
}
@Override
public void setAlpha(int alpha) {
}
@Override
public void setColorFilter(ColorFilter colorFilter) {
}
@Override
public int getOpacity() {
return PixelFormat.UNKNOWN;
}
}