100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > Android 自定义View 通过Paint和Canvas实现动态打勾对号效果

Android 自定义View 通过Paint和Canvas实现动态打勾对号效果

时间:2020-06-15 11:35:50

相关推荐

Android 自定义View 通过Paint和Canvas实现动态打勾对号效果

效果图

一开始是使用的最下面一种,发现canvas绘制线,一个点一个点绘制会非常的慢,于是改进成第一个,另外把对号单独提取出来了。

设计稿

分为一个圆和两条线,中间小的方框的边长就是代码中的hookSize,每次绘画的时候会先去找圆心,然后以圆心为中心去绘制正方形。

首先绘制圆,绘制完成后再分别绘制两条线,先画短的,画完短的再开始画长的。

几个注意点

1. 坐标系以左上角为原点,横X竖Y

2.在构造函数中通过getWidth来获取宽度得到的结果往往是0,在执行到onDraw的时候,控件大小才划定;

3.可以直接在布局文件中调用来使用

直接上代码

代码里都有注释

先上第三个的

DrawHookView.java

public class DrawHookView extends View {//绘制圆弧的进度值private int progress = 0;//线1的x轴private int line1_x = 0;//线1的y轴private int line1_y = 0;//线2的x轴private int line2_x = 0;//线2的y轴private int line2_y = 0;public DrawHookView(Context context) {super(context); }public DrawHookView(Context context, AttributeSet attrs) {super(context, attrs); }public DrawHookView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle); }//绘制@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);progress++;Paint paint = new Paint();//设置画笔颜色paint.setColor(getResources().getColor(R.color.colorPrimary));//设置圆弧的宽度paint.setStrokeWidth(5);//设置圆弧为空心paint.setStyle(Paint.Style.STROKE);//消除锯齿paint.setAntiAlias(true);//获取圆心的x坐标int center = getWidth() / 2;int center1 = center - getWidth() / 5;//圆弧半径int radius = getWidth() / 2 - 5;//定义的圆弧的形状和大小的界限RectF rectF = new RectF(center - radius -1, center - radius -1 ,center + radius + 1, center + radius + 1);//根据进度画圆弧canvas.drawArc(rectF, 235, -360 * progress / 100, false, paint);//先等圆弧画完,才话对勾if(progress >= 100) {if(line1_x < radius / 3) {line1_x++;line1_y++; }//画第一根线canvas.drawLine(center1, center, center1 + line1_x, center + line1_y, paint);if (line1_x == radius / 3) {line2_x = line1_x;line2_y = line1_y;line1_x++;line1_y++; }if (line1_x >= radius / 3 && line2_x <= radius) {line2_x++;line2_y--; }//画第二根线canvas.drawLine(center1 + line1_x - 1, center + line1_y, center1 + line2_x, center + line2_y, paint); }//每隔10毫秒界面刷新postInvalidateDelayed(10); }}

再上第一个的

DrawCheckMarkView.java

public class DrawCheckMarkView extends View {//绘制圆弧的进度值private int progress = 0;//打勾的起点int checkStartX;//线1的x轴增量private int line1X = 0;//线1的y轴增量private int line1Y = 0;//线2的x轴增量private int line2X = 0;//线2的y轴增量private int line2Y = 0;//增量值int step=2;//线的宽度private int lineThick = 4;//获取圆心的x坐标int center;//圆弧半径int radius;//定义的圆弧的形状和大小的界限RectF rectF;Paint paint;//控件大小float totalWidth;boolean secLineInited = false;public DrawCheckMarkView(Context context) {super(context);init(); }public DrawCheckMarkView(Context context, AttributeSet attrs) {super(context, attrs);Pattern p = pile("\\d*");Matcher m = p.matcher(attrs.getAttributeValue("/apk/res/android", "layout_width"));if (m.find()) {totalWidth = Float.valueOf(m.group()); }totalWidth = DisplayUtils.dp2px(context, totalWidth);init(); }public DrawCheckMarkView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);init(); }void init() {paint = new Paint();//设置画笔颜色paint.setColor(getResources().getColor(R.color.colorAccent));//设置圆弧的宽度paint.setStrokeWidth(lineThick);//设置圆弧为空心paint.setStyle(Paint.Style.STROKE);//消除锯齿paint.setAntiAlias(true);//获取圆心的x坐标center = (int) (totalWidth / 2);//圆弧半径radius = (int) (totalWidth / 2) - lineThick;checkStartX = (int) (center - totalWidth / 5);rectF = new RectF(center - radius,center - radius,center + radius,center + radius); }//绘制@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);Log.w("check mark", "drawing... # progress=" + progress);if (progress < 100)progress += step;//根据进度画圆弧canvas.drawArc(rectF, 235, -360 * progress / 100, false, paint);//先等圆弧画完,画对勾if (progress >= 100) {if (line1X < radius / 3) {line1X+=step;line1Y+=step; }//画第一根线canvas.drawLine(checkStartX, center, checkStartX + line1X, center + line1Y, paint);if (line1X >= radius / 3) {if (!secLineInited) {line2X = line1X;line2Y = line1Y;secLineInited=true; }line2X+=step;line2Y-=step;//画第二根线canvas.drawLine(checkStartX + line1X - lineThick / 2,center + line1Y, checkStartX + line2X, center + line2Y, paint); } }//每隔6毫秒界面刷新if (line2X <= radius)postInvalidateDelayed(6); }}

最后是中间的

DrawHookMarkView.java

public class DrawHookMarkView extends View {//打勾的起点int checkStartX;//线1的x轴增量private int line1X = 0;//线1的y轴增量private int line1Y = 0;//线2的x轴增量private int line2X = 0;//线2的y轴增量private int line2Y = 0;//增量值int step = 3;//线的宽度private int lineThick = 6;//获取圆心的x坐标int center;//圆弧半径int radius;Paint paint;//控件大小float totalWidth;boolean secLineInited = false;public DrawHookMarkView(Context context) {super(context);init(); }public DrawHookMarkView(Context context, AttributeSet attrs) {super(context, attrs);Pattern p = pile("\\d*");Matcher m = p.matcher(attrs.getAttributeValue("/apk/res/android", "layout_width"));if (m.find()) {totalWidth = Float.valueOf(m.group()); }totalWidth = DisplayUtils.dp2px(context, (int) totalWidth);init(); }public DrawHookMarkView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);init(); }void init() {paint = new Paint();//设置画笔颜色paint.setColor(getResources().getColor(R.color.colorPrimaryDark));//设置宽度paint.setStrokeWidth(lineThick);//设置空心paint.setStyle(Paint.Style.STROKE);//消除锯齿paint.setAntiAlias(true);//获取圆心的x坐标center = (int) (totalWidth / 2);//圆弧半径radius = (int) (totalWidth / 2) - lineThick;checkStartX = (int) (center - totalWidth / 5); }//绘制@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);if (line1X < radius / 3) {line1X += step;line1Y += step; }//画第一根线canvas.drawLine(checkStartX, center, checkStartX + line1X, center + line1Y, paint);if (line1X >= radius / 3) {if (!secLineInited) {line2X = line1X;line2Y = line1Y;secLineInited = true; }line2X += step;line2Y -= step;//画第二根线canvas.drawLine(checkStartX + line1X - lineThick / 2,center + line1Y, checkStartX + line2X, center + line2Y, paint); }//每隔6毫秒界面刷新if (line2X <= radius)postInvalidateDelayed(6); }}

一个px、dp、sp的转换工具类

DisplayUtils.java

public class DisplayUtils {public static float px2dp(final Context context, final float px) {return px / context.getResources().getDisplayMetrics().density; }public static float dp2px(final Context context, final float dp) {return dp * context.getResources().getDisplayMetrics().density; }/*** 将px值转换为sp值,保证文字大小不变* @param pxValue* @return*/public static int px2sp(Context context, float pxValue) {final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;return (int) (pxValue / fontScale + 0.5f); }/*** 将sp值转换为px值,保证文字大小不变* @param spValue* @return*/public static int sp2px(Context context, float spValue) {final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;return (int) (spValue * fontScale + 0.5f); }}

项目地址:github

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。