I have a button which I want to draw a rounded corner rectangle around it progressively after I clicked it. I try to draw bezier curves in a canvas however I could not find the formula of a bezier curve that could paint a rounded corner rectangle. So I end up drawing four straight lines to create a rectangle without rounded corners. Below is the relative code:
public class CustomProgressBar extends View{
private Paint paint = new Paint();
public HomeFragment mHomeFragment;
private Context context;
private Path path;
int width = 178;
int height = 58;
int x1=0;
int y1=0;
int x2=width;
int y2=0;
int x3=width;
int y3=height;
int x4=0;
int y4=height;
int currentLine=0;
int stepLength = 8;
public CustomProgressBar(Context context) {
super( context );
}
public CustomProgressBar(Context context, AttributeSet attrs) {
super( context, attrs );
this.context = context;
}
public CustomProgressBar(Context context, AttributeSet attrs, int defStyle) {
super( context, attrs, defStyle );
}
public void init(HomeFragment homeFragment){
this.mHomeFragment = homeFragment;
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(6);
paint.setColor(Color.rgb(203,156,76));
setCoordinates();
}
public void setCoordinates(){
new Thread(new Runnable() {
@Override
public void run() {
while (true){
switch (currentLine){
case 0:
if(x1<width) {
x1 += stepLength;
}else {
currentLine = 1;
}
break;
case 1:
if(y2<=height){
y2 += stepLength;
}else {
currentLine = 2;
}
break;
case 2:
if(x3>=0){
x3 -= stepLength;
}else {
currentLine = 3;
}
break;
case 3:
if(y4 >= 0){
y4 -= stepLength;
}else {
currentLine = 0;
x1 = 0;
y2 = 0;
x2 = width;
y2 = 0;
x3 = width;
y3 = height;
x4 = 0;
y4 = height;
}
break;
}
mHomeFragment.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
invalidate();
}
});
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
int max=100;
int progress=20;
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
switch (currentLine){
case 0:
canvas.drawLine(0, 0, x1, y1, paint);
break;
case 1:
canvas.drawLine(0, 0, x1, y1, paint);
canvas.drawLine(width, 0, x2, y2, paint);
break;
case 2:
canvas.drawLine(0, 0, x1, y1, paint);
canvas.drawLine(width, 0, x2, y2, paint);
canvas.drawLine(width, height, x3, y3, paint);
break;
case 3:
canvas.drawLine(0, 0, x1, y1, paint);
canvas.drawLine(width, 0, x2, y2, paint);
canvas.drawLine(width, height, x3, y3, paint);
canvas.drawLine(0, height, x4, y4, paint);
break;
}
}
}
Does anyone know how to draw a rounded corner rectangle with a canvas? Any help is much appreciated!
您应该使用drawRoundRect()
canvas.drawRoundRect(rect, rx, ry, paint);
It seems that there is not much information about how to draw round rectangle in java on the internet. So I modified a js demo which introduced by @pskink into a java version. Below is the full code:
class DrawRoundRectangle extends View {
Paint paint;
int strokWidth = 6;
Path path;
// define the rectangle
int offsetX = 75;
int offsetY = 100;
int horizLineLength = 240;
int vertLineLength = 40;
int cornerRadius = 100;
// calc some lengths for use in percent complete
int cornerLength = (int) (2 * cornerRadius * Math.PI);
int totalLength = cornerLength * 4 + horizLineLength * 2 + vertLineLength * 2;
MainActivity ma;
// calc at what accumulated length each part of the rect starts
int startT = 0;
int startTR = horizLineLength;
int startR = startTR + cornerLength;
int startBR = (int) (startR + vertLineLength);
int startB = startBR + cornerLength;
int startBL = startB + horizLineLength;
int startL = startBL + cornerLength;
int startTL = startL + vertLineLength;
// percent complete
int percent = 100;
private int accumLength;
private double d1;
private double d2;
private double d3;
private double d4;
private double d5;
private double d6;
private double d7;
private double d8;
int x1;
int y1;
int x2;
int y2;
int x;
int y;
double start;
double end1;
double end2;
double end3;
double end4;
Canvas canvas;
public DrawRoundRectangle(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
paint = new Paint();
paint.setStrokeWidth(strokWidth);
paint.setColor(Color.rgb(203,156,76));
path = new Path();
Paint.Style style = paint.getStyle();
paint.setStyle(style.STROKE);
}
float progress = 0;
float stepLength = 0.5f;
@Override
protected void onDraw(Canvas canvas) {
//canvas.drawPath(segment, paint);
this.canvas = canvas;
drawPercentRect(progress);
progress+=stepLength;
if(progress >= 100){
progress = 0;
path.reset();
}
}
// draw the radius rectangle
private void resetVars(){
d1=0;
d2=0;
d3=0;
d4=0;
d5=0;
d6=0;
d7=0;
d8=0;
end1=0;
end2=0;
end3=0;
end4=0;
}
private void drawPercentRect(float percent) {
// percent expressed as a length-traveled-along-rect
accumLength = (int) (percent / 100 * totalLength);
// clear the canvas
//ctx.clearRect(0, 0, canvas.width, canvas.height);
// top line
resetVars();
d1 = accumLength - startT;
d1 = Math.min(d1, horizLineLength);
stepLength = 0.5f;
if (d1 > 0) {
x1 = offsetX + cornerRadius;
y1 = offsetY;
x2 = (int) (offsetX + cornerRadius + d1);
y2 = offsetY;
drawLine(x1, y1, x2, y2);
}
// top-right corner
d2 = accumLength - startTR;
d2 = Math.min(d2, cornerLength);
if (d2 > 0) {
x = offsetX + 50 + horizLineLength;
y = offsetY;
start = 270;
end1 = 90*(d2/cornerLength);
drawCorner(x, y, start, end1);
}
// right line
d3 = accumLength - startR;
d3 = Math.min(d3, vertLineLength);
if (d3 > 0) {
x1 = offsetX + cornerRadius + horizLineLength + cornerRadius/2;
y1 = offsetY + cornerRadius/2;
x2 = offsetX + cornerRadius + horizLineLength + cornerRadius/2;
y2 = (int) (offsetY + cornerRadius/2 + d3);
drawLine(x1, y1, x2, y2);
}
// bottom-right corner
d4 = accumLength - startBR;
d4 = Math.min(d4, cornerLength);
if (d4 > 0) {
x = offsetX + horizLineLength+cornerRadius/2;
y = offsetY + vertLineLength;
start = 0;
//end = (int) ((d / cornerLength) * Math.PI / 2);
end2 = 90*(d4/cornerLength);
drawCorner(x, y, start, end2);
}
// bottom line
d5 = accumLength - startB;
d5 = Math.min(d5, horizLineLength);
if (d5 > 0) {
x1 = offsetX + cornerRadius + horizLineLength;
y1 = offsetY + cornerRadius + vertLineLength;
x2 = (int) (offsetX + cornerRadius + horizLineLength - d5);
y2 = offsetY + cornerRadius + vertLineLength;
drawLine(x1, y1, x2, y2);
}
// bottom-left corner
d6 = accumLength - startBL;
d6 = Math.min(d6, cornerLength);
if (d6 > 0) {
x = offsetX + cornerRadius/2;
y = offsetY + vertLineLength;
start = 90;
end3 = 90*(d6/cornerLength);
drawCorner(x, y, start, end3);
}
// left line
d7 = accumLength - startL;
d7 = Math.min(d7, vertLineLength);
if (d7 > 0) {
x1 = offsetX + cornerRadius/2;
y1 = offsetY + cornerRadius/2 + vertLineLength;
x2 = offsetX + cornerRadius/2;
y2 = (int) (offsetY + cornerRadius/2 + vertLineLength - d7);
drawLine(x1, y1, x2, y2);
}
// top-left corner
d8 = accumLength - startTL;
d8 = Math.min(d8, cornerLength);
if (d8 > 0) {
x = offsetX+cornerRadius/2;
y = offsetY;
start = 180;
end4 = 90*(d8/cornerLength);
drawCorner(x, y, start, end4);
}
}
private void drawLine(int x1, int y1, int x2, int y2) {
//ctx.beginPath();
path.moveTo(x1, y1);
path.lineTo(x2, y2);
canvas.drawPath(path, paint);
//ctx.stroke();
}
private void drawCorner(int x, int y, double start, double end) {
if(end<90){
progress+=4*stepLength;
}
path.arcTo(x, y, x + cornerRadius, y + cornerRadius, (float) start(float) end,true);
canvas.drawPath(path, paint);
}
public void start(final MainActivity ma) {
this.ma = ma;
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
ma.runOnUiThread(new Runnable() {
@Override
public void run() {
invalidate();
}
});
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.