自定义属性 来实现 ProgressBar 圆形进度条
来源:互联网 发布:淘宝显示原价和折扣价 编辑:程序博客网 时间:2024/06/11 21:07
实现圆形进度条的拖拽,点击实现效果如下图所示:
自定义属性
在src/values中新建attrs.xml
<?xml version="1.0" encoding="utf-8"?><resources> <declare-styleable name="XProgressBar"> <attr name="progress" format="integer"/> <attr name="max" format="integer"/> <attr name="smallCircleColor" format="color"/> <attr name="progressColor" format="color"/> <attr name="textColor" format="color"/> <attr name="borderOutWidth" format="dimension"/> </declare-styleable></resources>
在主布局中引用自定义属性
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.xykj.xprogressbar.MainActivity" android:orientation="vertical"> <com.xykj.view.XProgressBar android:layout_width="match_parent" android:layout_height="100dp" app:progress="30" app:progressColor="@color/colorAccent"/> <com.xykj.view.XSeekBar android:layout_width="match_parent" android:layout_height="300dp" android:layout_marginTop="10dp"/></LinearLayout>
定义类XProgressBar继承View
public class XProgressBar extends View { protected int radius; //小圆半径 private int smallRadius; //中心点 protected Point center; //当前进度 protected int progress; //总进度 protected int max = 100; //外部的进度的宽度 private int borderOutWidth = 20; //内部小圆的颜色 private int smallCircleColor = 0xff00A2E8; //进度的颜色 private int progressColor = 0xff22B14C; //文本颜色 private int textColor = 0xFFFFFFFF; //画笔 private Paint paint; //进度弧度所在的矩形区域 private RectF progressRect; public XProgressBar(Context context) { super(context); init(); } public XProgressBar(Context context, @Nullable AttributeSet attrs) { super(context, attrs); TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.XProgressBar); progress = ta.getInteger(R.styleable.XProgressBar_progress, 0); max = ta.getInteger(R.styleable.XProgressBar_max, 100); borderOutWidth = ta.getDimensionPixelSize(R.styleable.XProgressBar_borderOutWidth, 20); smallCircleColor = ta.getColor(R.styleable.XProgressBar_smallCircleColor, 0xff00A2E8); progressColor = ta.getColor(R.styleable.XProgressBar_progressColor, 0xff22B14C); textColor = ta.getColor(R.styleable.XProgressBar_textColor, 0xffffffff); ta.recycle(); init(); } private void init() { center = new Point(); progressRect = new RectF(); //初始化画笔 paint = new Paint(); paint.setAntiAlias(true); paint.setStrokeWidth(borderOutWidth); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int width = getDefaultSize(80, widthMeasureSpec); int height = getDefaultSize(80, heightMeasureSpec); //记录中心点 center.set(width / 2, height / 2); //取小的一边作为显示的最大半径 radius = width > height ? center.y : center.x; progressRect.set(center.x - radius + borderOutWidth / 2, center.y - radius + borderOutWidth / 2, center.x + radius - borderOutWidth / 2, center.y + radius - borderOutWidth / 2); if (smallRadius == 0) { smallRadius = radius - borderOutWidth - 3; paint.setTextSize(smallRadius / 2); } setMeasuredDimension(width, height); } public static int getDefaultSize(int size, int measureSpec) { int result = size; int specMode = MeasureSpec.getMode(measureSpec); if (specMode == MeasureSpec.EXACTLY) { int specSize = MeasureSpec.getSize(measureSpec); if (specSize > size) { result = specSize; } } return result; } Rect textRect = new Rect(); @Override protected void onDraw(Canvas canvas) { //画小圆背景(实心) paint.setStyle(Paint.Style.FILL); paint.setColor(smallCircleColor); canvas.drawCircle(center.x, center.y, smallRadius, paint); //画文本 String text = progress + "%"; //0% 50% 100% paint.getTextBounds(text, 0, text.length(), textRect); paint.setColor(textColor); canvas.drawText(text, center.x - textRect.centerX(), center.y - textRect.centerY(), paint); //画进度的弧度 paint.setStyle(Paint.Style.STROKE); paint.setColor(progressColor); int degress = getDegress(); canvas.drawArc(progressRect, -90, degress, false, paint); } protected int getDegress(){ return 360 * progress / max; } public int getProgress() { return progress; } public void setProgress(int progress) { if (this.progress != progress && progress <= max) { this.progress = progress; invalidate(); } } public int getMax() { return max; } public void setMax(int max) { this.max = max; } public int getBorderOutWidth() { return borderOutWidth; } public void setBorderOutWidth(int borderOutWidth) { this.borderOutWidth = borderOutWidth; } public int getSmallCircleColor() { return smallCircleColor; } public void setSmallCircleColor(int smallCircleColor) { if(this.smallCircleColor != smallCircleColor) { this.smallCircleColor = smallCircleColor; invalidate(); } } public int getProgressColor() { return progressColor; } public void setProgressColor(int progressColor) { if(this.progressColor != progressColor) { this.progressColor = progressColor; invalidate(); } } public int getTextColor() { return textColor; } public void setTextColor(int textColor) { if(this.textColor != textColor) { this.textColor = textColor; invalidate(); } }}
定义类XSeekBar继承XProgressBar
public class XSeekBar extends XProgressBar { public XSeekBar(Context context) { super(context); } public XSeekBar(Context context, @Nullable AttributeSet attrs) { super(context, attrs); } private int degress; @Override public boolean onTouchEvent(MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: if (null != onXSeekBarChangeListener) { onXSeekBarChangeListener.onStartTrackingTouch(this); } case MotionEvent.ACTION_MOVE: float x = event.getX(); float y = event.getY(); float dis = getDistence(x, y); if (dis >= radius - 10 && dis <= radius + 10) { //在圆上,计算触控点和圆顶部切线的tan值 float tanValue = (y - center.y + radius) / Math.abs(x - center.x); //反tan获取触控点和顶部切线的夹角(0-2PI) float dPi = (float) Math.atan(tanValue); //触控点和顶部切线夹角的2倍即为弧度角 int d = (int) Math.toDegrees(dPi); if (x < center.x) { d = 180 - d; } degress = d * 2; if (degress > 360) { degress = 360; } else if (degress < 0) { degress = 0; } progress = max * degress / 360; if (null != onXSeekBarChangeListener) { onXSeekBarChangeListener.onProgressChanged(this, progress, true); } invalidate(); } break; case MotionEvent.ACTION_UP: if (null != onXSeekBarChangeListener) { onXSeekBarChangeListener.onStopTrackingTouch(this); } break; } return true; } /** * 计算触控点到圆心的距离 * * @param x * @param y * @return */ private float getDistence(float x, float y) { return (float) Math.sqrt(Math.pow(x - center.x, 2) + Math.pow(y - center.y, 2)); } @Override protected int getDegress() { return degress; } @Override public void setProgress(int progress) { if (this.progress != progress && null != onXSeekBarChangeListener) { onXSeekBarChangeListener.onProgressChanged(this, progress, false); } super.setProgress(progress); } public OnXSeekBarChangeListener getOnXSeekBarChangeListener() { return onXSeekBarChangeListener; } public void setOnXSeekBarChangeListener(OnXSeekBarChangeListener onXSeekBarChangeListener) { this.onXSeekBarChangeListener = onXSeekBarChangeListener; } private OnXSeekBarChangeListener onXSeekBarChangeListener; public interface OnXSeekBarChangeListener { void onStartTrackingTouch(XSeekBar bar); void onProgressChanged(XSeekBar seekBar, int progress, boolean fromUser); void onStopTrackingTouch(XSeekBar bar); }}
阅读全文
0 0
- 自定义属性 来实现 ProgressBar 圆形进度条
- 自定义圆形进度条 progressBar
- 自定义属性实现圆形进度条
- 【Android进度条】三种方式实现自定义圆形进度条ProgressBar
- 【Android进度条】三种方式实现自定义圆形进度条ProgressBar
- 【Android进度条】三种方式实现自定义圆形进度条ProgressBar
- 【Android进度条】三种方式实现自定义圆形进度条ProgressBar
- 【Android进度条】三种方式实现自定义圆形进度条ProgressBar
- 三种方式实现自定义圆形进度条ProgressBar
- Android 三种方式实现自定义圆形进度条ProgressBar
- ProgressBar(进度条)-自定义圆形进度条
- Android ProgressBar高级自定义水平/圆形进度条
- 简单的自定义圆形进度条ProgressBar
- 自定义属性,实现自定义画板和实现圆形进度条
- ProgressBar(进度条)-使用动画来替代圆形进度条
- 圆形进度条ProgressBar 的实现方式
- android ProgressBar 实现自定义进度条
- 自定义进度条ProgressBar的实现
- Beyond Compare如何比较两个文件夹差异
- 《利用python进行数据分析》ch04
- Apache poi常用方法
- Codeforces 876A Trip For Meal 贪心
- VS2017 安装 R 组件后出现警告
- 自定义属性 来实现 ProgressBar 圆形进度条
- ubuntu16.04.3下安装tensorflow
- 【转载】梯度下降算法详解
- canny边缘检测算法为什么需要两个阈值?
- 【LeetCode】C# 98、Validate Binary Search Tree
- PHP微信支付之扫码支付
- 搭建安全的Docker Private Registry完全指南
- 计时器
- 洛谷P1080:国王游戏 (贪心+高精度)