关于bezier:在android中绘制自定义视图
draw custom views in android
我想在 android 中绘制类似的东西,将其用作按钮。怎么做?任何链接或建议?是贝塞尔曲线吗?
相关讨论
- 将其保存为可绘制文件夹中的PNG,并将其放在按钮上...
如评论中所述,您可以创建一个 PNG 并直接使用它。如果您希望侧面独立于曲线缩放,您可以对图像进行 9-patch。
根据这篇文章,您现在可以选择在 xml 中定义可绘制的路径。但仅适用于 Lollipop 及以上。
最后,您可以创建一个基本按钮并使用
编辑:
我有一点时间来创建一个
在我的实现中,我使用了渐变而不是纯色,因为它不会对实现产生影响,而且它是一个更通用的示例。
public class PathView extends View { private Paint paintFill; private Paint paintLine; private Paint paintClear; private Path path; private int colour; private float x0; private float y0; private float x1; private float y1; private float x2; private float y2; private float x3; private float y3; public PathView(Context context) { super(context); } public PathView(Context context, AttributeSet attrs) { super(context, attrs); } public PathView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public PathView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); initialize(); } private void initialize() { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { // Path clipping uses hardware acceleration which is unavailable from 11 to 18 // https://stackoverflow.com/questions/8895677/work-around-canvas-clippath-that-is-not-supported-in-android-any-more setLayerType(LAYER_TYPE_SOFTWARE, null); } paintFill = new Paint(); paintFill.setAntiAlias(true); LinearGradient gradient = new LinearGradient(0, getHeight(), 0, 0, Color.WHITE, colour, Shader.TileMode.CLAMP); // Vertical gradient paintFill.setShader(gradient); paintLine = new Paint(); paintLine.setColor(colour); paintLine.setStrokeWidth(1.5f); paintLine.setStrokeCap(Paint.Cap.ROUND); paintLine.setStyle(Paint.Style.STROKE); paintLine.setAntiAlias(true); paintClear = new Paint(); paintClear.setColor(Color.WHITE); paintClear.setAntiAlias(true); } public int getColour() { return colour; } public void setColour(int colour) { this.colour = colour; initialize(); invalidate(); } public void setVars(float x1, float y1, float x2, float y2) { // When the vars changes, the path needs to be updated. // In order to make clipping easier, we draw lines from [x0, y0] to // [x0, getHeight] and [x3, y3] to [x3, getHeight]. // This makes the fill section of the path everything below the path. path = new Path(); float cx = getWidth() / 2; float cy = getHeight() / 2; this.x0 = 0; this.y0 = cy + y1; this.x1 = x1; this.y1 = cy + y1; this.x2 = x2; this.y2 = cy + y2; this.x3 = getWidth(); this.y3 = cy + y2; // Move to bottom, draw up path.moveTo(this.x0, getHeight()); path.lineTo(this.x0 - paintLine.getStrokeMiter(), this.y0); path.cubicTo(this.x1, this.y1, this.x2, this.y2, this.x3, this.y3); // Draw down path.lineTo(this.x3 + paintLine.getStrokeMiter(), getHeight()); invalidate(); } @Override public void draw(Canvas canvas) { super.draw(canvas); if (path != null && paintFill != null) { // Draw gradient background first, and then clip the irrelevant section away. // This will let our gradient be uniform irrespective of the vars used. canvas.drawRect(x0, 0, x3, getHeight(), paintFill); canvas.save(); canvas.clipPath(path, Region.Op.DIFFERENCE); canvas.drawRect(x0, 0, x3, getHeight(), paintClear); canvas.restore(); canvas.drawPath(path, paintLine); } } } |