From 8724902e4dc8b862f9887368a3e2bd79c6f0e1ca Mon Sep 17 00:00:00 2001 From: fairytale110 Date: Mon, 15 Oct 2018 22:09:56 +0800 Subject: [PATCH 01/11] Update README.md --- README.md | 47 +++++++++++++++++++++-------------------------- 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index d4df258..cdadc2d 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,30 @@ -## SquaresLoadingView -> A SquaresLoadingView based on android.View, nicely rotation、easy to use. +## BezierSeekBar +> Beautiful custom View, SeekBar selector, easy to use, and rich in customization. [![API](https://img.shields.io/badge/API-19%2B-brightgreen.svg)](https://android-arsenal.com/api?level=19) [![License](https://img.shields.io/badge/license-Apache%202-green.svg)](https://www.apache.org/licenses/LICENSE-2.0) -[![Download](https://img.shields.io/badge/Download-1.0.0-brightgreen.svg) ](https://github.com/fairytale110/SquaresLoadingView/archive/1.0.0.zip) +[![Download](https://img.shields.io/badge/Download-1.0.0-brightgreen.svg) ](https://github.com/fairytale110/BezierSeekBar/archive/1.0.1.zip) ### Preview -![preview.gif](https://upload-images.jianshu.io/upload_images/1781452-f256a5f5da4f9026.gif?imageMogr2/auto-orient/strip) - -### Features - -Supported functions: - -- [x] Optionally configure the colors of each square -- [x] Manually stop and start the animation -- [x] Configurable anim's speed - -- [x] Support the padding settings +![preview.gif](https://github.com/fairytale110/BezierSeekBar/raw/master/release/preview_1.0.1.gif) +### DEMO -Support will be forthcoming: + [![Download Demo APK](https://img.shields.io/badge/Download%20APK-1.0.1-brightgreen.svg) ](https://github.com/fairytale110/BezierSeekBar/raw/master/release/app-release.apk) +or you can scan this QRcode to download -- [ ] Manual rotation +![APK 1.0.1](https://github.com/fairytale110/BezierSeekBar/raw/master/release/demo_1.0.1_qrcode.png) -- [ ] Refresh header view support +### Features -- [ ] Etc +Supported functions: +- [x] Easy to use! +- [x] Optionally configure the colors of ALL +- [x] Smooth Bezier animation effects +- [x] Freely configure the selection interval +- [x] Dynamic monitoring of changes in selection ### How to @@ -45,9 +42,9 @@ Add it in your root build.gradle at the end of repositories: ``` Step 2. Add the dependency ``` - dependencies { - implementation 'com.github.fairytale110:SquaresLoadingView:1.0.0' - } + dependencies { + implementation 'com.github.fairytale110:BezierSeekBar:1.0.1' + } ``` ### Usage @@ -106,12 +103,8 @@ fairytale110@foxmail.com > 掘金: https://juejin.im/user/596d91ee6fb9a06bb874a800 -> CSDN: https://blog.csdn.net/LJYBQ - -> MY WEB: https://nicesky.tech - -## LICENSE +### LICENSE ``` Copyright 2018 fairytale110 @@ -128,3 +121,5 @@ fairytale110@foxmail.com See the License for the specific language governing permissions and limitations under the License. ``` + +### Github :https://github.com/fairytale110/BezierSeekBar From 84de829c3c21214b15f8f02429b283f4149de645 Mon Sep 17 00:00:00 2001 From: fairytale110 Date: Tue, 16 Oct 2018 10:18:16 +0800 Subject: [PATCH 02/11] Create README_CN --- README_CN | 125 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 README_CN diff --git a/README_CN b/README_CN new file mode 100644 index 0000000..b61b266 --- /dev/null +++ b/README_CN @@ -0,0 +1,125 @@ + +## BezierSeekBar +> 优雅的区间选择器,贝塞尔曲线样式,丰富的自定义内容,简单易懂的上手方式, + +[![API](https://img.shields.io/badge/API-19%2B-brightgreen.svg)](https://android-arsenal.com/api?level=19) +[![License](https://img.shields.io/badge/license-Apache%202-green.svg)](https://www.apache.org/licenses/LICENSE-2.0) +[![Download](https://img.shields.io/badge/Download-1.0.0-brightgreen.svg) ](https://github.com/fairytale110/BezierSeekBar/archive/1.0.1.zip) + +### 预览 + +![preview.gif](https://github.com/fairytale110/BezierSeekBar/raw/master/release/preview_1.0.1.gif) + +### 演示 DEMO + + [![Download Demo APK](https://img.shields.io/badge/Download%20APK-1.0.1-brightgreen.svg) ](https://github.com/fairytale110/BezierSeekBar/raw/master/release/app-release.apk) +or you can scan this QRcode to download + +![APK 1.0.1](https://github.com/fairytale110/BezierSeekBar/raw/master/release/demo_1.0.1_qrcode.png) + +### 功能 + + +- [x] 超级简单的使用方式。 + +- [x] 所有内容可自定义颜色 +- [x] 顺滑的交互动画 +- [x] 自由配置样式 +- [x] 选择区间可控、实时监听选择结果。 + +### How to + +仓库引用: + +步骤 1. 添加 JitPack 依赖 到你的 build.gradle: +``` + allprojects { + repositories { + ... + maven { url 'https://jitpack.io' } + } + } +``` +步骤 2. 添加仓库 +``` + dependencies { + implementation 'com.github.fairytale110:BezierSeekBar:1.0.1' + } +``` + +### 使用方式 + +```java + +``` +或者 +```java + + private void createBsbar() { + fram.setBackgroundColor(Color.WHITE); + + BezierSeekBar seekBar = new BezierSeekBar(this); + seekBar.setColorBall(Color.BLACK); + seekBar.setColorLine(Color.BLACK); + seekBar.setColorValueSelected(Color.WHITE); + seekBar.setColorValue(Color.BLACK); + seekBar.setColorBgSelected(Color.BLACK); + seekBar.setValueMax(150); + seekBar.setValueMin(20); + seekBar.setValueSelected(60); + seekBar.setUnit("mm"); + seekBar.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + seekBar.setSelectedListener(new OnSelectedListener() { + @Override + public void onSelected(int value) { + checkLength(value); + } + }); + fram.addView(seekBar); + //checkLength(seekBar.getValueSelected()); + } +``` + +### 参与贡献 +fairytale110@foxmail.com + + +### 作者 +fairytale110@foxmail.com +> 简书: http://jianshu.com/u/d95b27ffdd3c + +> 掘金: https://juejin.im/user/596d91ee6fb9a06bb874a800 + + +### 开源协议 + +``` + Copyright 2018 fairytale110 + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +``` + +### Github :https://github.com/fairytale110/BezierSeekBar From f7b3da3f6b1c020a72eef42b021c4e2ddd1fb22d Mon Sep 17 00:00:00 2001 From: fairytale110 Date: Tue, 16 Oct 2018 10:18:48 +0800 Subject: [PATCH 03/11] Rename README_CN to README_CN.md --- README_CN => README_CN.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename README_CN => README_CN.md (100%) diff --git a/README_CN b/README_CN.md similarity index 100% rename from README_CN rename to README_CN.md From a0d83c17875faf04d1e40d145cead3e15e2f6fcf Mon Sep 17 00:00:00 2001 From: fairytale110 Date: Tue, 16 Oct 2018 10:20:13 +0800 Subject: [PATCH 04/11] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index cdadc2d..38a5dc7 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ [![License](https://img.shields.io/badge/license-Apache%202-green.svg)](https://www.apache.org/licenses/LICENSE-2.0) [![Download](https://img.shields.io/badge/Download-1.0.0-brightgreen.svg) ](https://github.com/fairytale110/BezierSeekBar/archive/1.0.1.zip) +[中文README](https://github.com/fairytale110/BezierSeekBar/blob/master/README_CN.md) ### Preview ![preview.gif](https://github.com/fairytale110/BezierSeekBar/raw/master/release/preview_1.0.1.gif) From 8e5cc0f2d2cd59239313c6a24fb1c8e1ceca0dff Mon Sep 17 00:00:00 2001 From: fairytale110 Date: Thu, 18 Oct 2018 10:59:09 +0800 Subject: [PATCH 05/11] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 38a5dc7..7578a1e 100644 --- a/README.md +++ b/README.md @@ -102,7 +102,7 @@ fairytale110@foxmail.com fairytale110@foxmail.com > 简书: http://jianshu.com/u/d95b27ffdd3c -> 掘金: https://juejin.im/user/596d91ee6fb9a06bb874a800 +> 掘金: https://juejin.im/user/596d91ee6fb9a06bb874a800/pins ### LICENSE From b1713a939d47bae041f247c0d9c028a5312a20c2 Mon Sep 17 00:00:00 2001 From: fairytale110 Date: Thu, 18 Oct 2018 11:00:11 +0800 Subject: [PATCH 06/11] Update README_CN.md --- README_CN.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README_CN.md b/README_CN.md index b61b266..545579c 100644 --- a/README_CN.md +++ b/README_CN.md @@ -101,7 +101,7 @@ fairytale110@foxmail.com fairytale110@foxmail.com > 简书: http://jianshu.com/u/d95b27ffdd3c -> 掘金: https://juejin.im/user/596d91ee6fb9a06bb874a800 +> 掘金: https://juejin.im/user/596d91ee6fb9a06bb874a800/pins ### 开源协议 From 7a32e47e0c21f22e720555d69c483703ad3ac935 Mon Sep 17 00:00:00 2001 From: fairytale110 Date: Thu, 18 Oct 2018 11:02:00 +0800 Subject: [PATCH 07/11] Update README_CN.md --- README_CN.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README_CN.md b/README_CN.md index 545579c..af81680 100644 --- a/README_CN.md +++ b/README_CN.md @@ -13,7 +13,8 @@ ### 演示 DEMO [![Download Demo APK](https://img.shields.io/badge/Download%20APK-1.0.1-brightgreen.svg) ](https://github.com/fairytale110/BezierSeekBar/raw/master/release/app-release.apk) -or you can scan this QRcode to download + +或者直接手机扫码下载: ![APK 1.0.1](https://github.com/fairytale110/BezierSeekBar/raw/master/release/demo_1.0.1_qrcode.png) @@ -27,7 +28,7 @@ or you can scan this QRcode to download - [x] 自由配置样式 - [x] 选择区间可控、实时监听选择结果。 -### How to +### 怎么使用? 仓库引用: @@ -65,7 +66,7 @@ or you can scan this QRcode to download android:layout_height="wrap_content" /> ``` -或者 +或者 ```java private void createBsbar() { From beb87edb138f0a1a5fab8b967dd9699813b3791d Mon Sep 17 00:00:00 2001 From: fairytale110 Date: Wed, 14 Nov 2018 10:16:36 +0800 Subject: [PATCH 08/11] update Gradle to newest version --- .idea/encodings.xml | 6 ------ .idea/misc.xml | 8 ++++++-- .idea/modules.xml | 3 --- .idea/vcs.xml | 2 +- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 4 ++-- libBezierSeekBar/build.gradle | 2 +- 7 files changed, 11 insertions(+), 16 deletions(-) delete mode 100644 .idea/encodings.xml diff --git a/.idea/encodings.xml b/.idea/encodings.xml deleted file mode 100644 index c2bae49..0000000 --- a/.idea/encodings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 99202cc..e0d5b93 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -5,22 +5,26 @@ diff --git a/.idea/modules.xml b/.idea/modules.xml index 214b348..5996cc9 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -3,11 +3,8 @@ - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 94a25f7..35eb1dd 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/build.gradle b/build.gradle index 605e67a..9ed1bf8 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.1.4' + classpath 'com.android.tools.build:gradle:3.2.1' // NOTE: Do not place your application dependencies here; they belong diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ee9ab38..4bff3bb 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Mon Oct 15 17:14:40 CST 2018 +#Wed Nov 14 10:07:24 CST 2018 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip diff --git a/libBezierSeekBar/build.gradle b/libBezierSeekBar/build.gradle index 66efac9..ef636cd 100644 --- a/libBezierSeekBar/build.gradle +++ b/libBezierSeekBar/build.gradle @@ -24,7 +24,7 @@ android { dependencies { - implementation rootProject.ext.dependencies.appCompat + //implementation rootProject.ext.dependencies.appCompat testImplementation rootProject.ext.dependencies.junit implementation fileTree(dir: 'libs', include: ['*.jar']) //implementation 'com.android.support.constraint:constraint-layout:1.1.3' From fcecc3137cafbcce4723f7b007d8dc7b928a809a Mon Sep 17 00:00:00 2001 From: fairytale110 Date: Thu, 15 Nov 2018 19:50:55 +0800 Subject: [PATCH 09/11] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 7578a1e..e138a04 100644 --- a/README.md +++ b/README.md @@ -94,6 +94,9 @@ or } ``` +### blog(CN) +https://juejin.im/post/5bebed2fe51d450df867c3c1 + ### Participate in the contribution fairytale110@foxmail.com From b7fe2abfaf6920331df7d4735b2d480676932c08 Mon Sep 17 00:00:00 2001 From: fairytale110 Date: Thu, 15 Nov 2018 19:51:28 +0800 Subject: [PATCH 10/11] Update README_CN.md --- README_CN.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README_CN.md b/README_CN.md index af81680..e9e6c6f 100644 --- a/README_CN.md +++ b/README_CN.md @@ -94,6 +94,10 @@ } ``` +### 源码解析 + +https://juejin.im/post/5bebed2fe51d450df867c3c1 + ### 参与贡献 fairytale110@foxmail.com From 30bfcaed35e6d8e46801ec6517cc62096dc5308f Mon Sep 17 00:00:00 2001 From: fairytale110 <30248926+fairytale110@users.noreply.github.com> Date: Sat, 4 May 2019 13:28:09 +0800 Subject: [PATCH 11/11] fix #issues1 fix #issues1 --- .../nicesky/bezierseekbar/BezierSeekBar.java | 1027 +++++++++-------- 1 file changed, 515 insertions(+), 512 deletions(-) diff --git a/libBezierSeekBar/src/main/java/tech/nicesky/bezierseekbar/BezierSeekBar.java b/libBezierSeekBar/src/main/java/tech/nicesky/bezierseekbar/BezierSeekBar.java index bd3830c..272ade3 100644 --- a/libBezierSeekBar/src/main/java/tech/nicesky/bezierseekbar/BezierSeekBar.java +++ b/libBezierSeekBar/src/main/java/tech/nicesky/bezierseekbar/BezierSeekBar.java @@ -1,513 +1,516 @@ -package tech.nicesky.bezierseekbar; - -import android.animation.ValueAnimator; -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.graphics.Path; -import android.graphics.Point; -import android.graphics.Rect; -import android.graphics.RectF; -import android.graphics.Typeface; -import android.os.Build; -import android.support.annotation.Nullable; -import android.support.annotation.RequiresApi; -import android.util.AttributeSet; -import android.util.Log; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewGroup; -import android.view.animation.LinearInterpolator; - -import java.text.DecimalFormat; - -/** - * @author fairytale110 - * @class tech/nicesky/bezierseekbar/BezierSeekBar.java:17 - * @date on 2018/10/12-下午1:53 - * @email fairytale110@foxmail.com - * @description: - */ -public class BezierSeekBar extends View { - - private Context context; - private DecimalFormat decimalFormat; - private int mPaddingStart; - private int mPaddingEnd; - private int mPaddingTop; - private int mPaddingBottom; - - private int width; - private int height; - - /** - * View默认高度 - */ - private int diameterDefault = 300; - - /** - * 曲线弧高度 - */ - private float bezierHeight = 50F; - - private float circleRadiusMin = 15F; - private float circleRadiusMax = circleRadiusMin * 1.5F; - private float circleRadius = circleRadiusMin; - - /** - * 圆与线的垂直距离 - */ - private float spaceToLine = circleRadiusMin * 2F; - - /** - * 触摸点的坐标 - */ - private float fingerX, fingerXDefault, fingerYDefault; - - private float textSelectedSize = 20f; - - private float textSize = 12f; - - private int colorValue, colorValueSelected, colorLine, colorBall, colorBgSelected; - - /** - * 贝塞尔线的path - */ - private Path bezierPath; - - /** - * 曲线画笔 - */ - private Paint bezierPaint, ballPaint, textPaint, textDownPaint; - - /***/ - private Point fingerPoint; - - private Paint txtSelectedBgPaint; - - private RectF bgRect; - - private String unit = "kg"; - private int valueMin, valueMax, valueSelected; - private boolean animInFinshed = false; - - private ValueAnimator animatorFingerIn, animatorFingerOut; - - private OnSelectedListener selectedListener; - - /** - * @param context - */ - - public BezierSeekBar(Context context) { - super(context); - init(context, null); - - } - - public BezierSeekBar(Context context, @Nullable AttributeSet attrs) { - super(context, attrs); - init(context, attrs); - } - - public BezierSeekBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - init(context, attrs); - } - - @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) - public BezierSeekBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - init(context, attrs); - } - - - private void init(Context context, AttributeSet attrs) { - this.context = context; - - decimalFormat = new DecimalFormat("#"); -// diameterDefault = (int) dp2px(context, 300); -// -// this.circleRadiusMin = dp2px(context, 12F); -// this.circleRadiusMax = circleRadiusMin * 1.5F; -// this.circleRadius = circleRadiusMin; -// this.spaceToLine = circleRadiusMin *2F; - - textSelectedSize = dp2px(context, 20F); - textSize = dp2px(context, 12F); - - this.valueMax = 200; - this.valueMin = 30; - - this.colorBall = this.colorLine = this.colorValue = Color.BLACK; - this.colorValueSelected = Color.WHITE; - this.fingerX = 100F; - - initAttr(context, attrs); - - this.bgRect = new RectF(); - - this.bezierPaint = new Paint(); - this.bezierPaint.setAntiAlias(true); - this.bezierPaint.setStyle(Paint.Style.STROKE); - this.bezierPaint.setColor(colorLine); - this.bezierPaint.setStrokeWidth(2F); - - this.textPaint = new Paint(); - this.textPaint.setAntiAlias(true); - this.textPaint.setStyle(Paint.Style.FILL); - this.textPaint.setColor(colorValue); - this.textPaint.setStrokeWidth(2F); - Typeface font = Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD); - this.textPaint.setTypeface(font); - this.textPaint.setTextSize(textSelectedSize); - - this.txtSelectedBgPaint = new Paint(); - this.txtSelectedBgPaint.setAntiAlias(true); - this.txtSelectedBgPaint.setColor(colorBgSelected); - this.txtSelectedBgPaint.setStyle(Paint.Style.FILL); - - this.textDownPaint = new Paint(); - this.textDownPaint.setAntiAlias(true); - this.textDownPaint.setStyle(Paint.Style.FILL); - this.textDownPaint.setColor(colorValue); - this.textDownPaint.setStrokeWidth(2F); - this.textDownPaint.setTextSize(textSize); - - this.ballPaint = new Paint(); - this.ballPaint.setAntiAlias(true); - this.ballPaint.setStyle(Paint.Style.FILL); - this.ballPaint.setColor(colorBall); - - this.bezierPath = new Path(); - - this.fingerXDefault = 200f; - this.fingerYDefault = 200f; - - this.bezierPath.moveTo((float) fingerX, (float) 100); - - this.animatorFingerIn = ValueAnimator.ofFloat(0f, 1f); - this.animatorFingerIn.setDuration(200L); - this.animatorFingerIn.setInterpolator(new LinearInterpolator()); - - this.animatorFingerOut = ValueAnimator.ofFloat(1f, 0f); - this.animatorFingerOut.setDuration(200L); - this.animatorFingerOut.setInterpolator(new LinearInterpolator()); - - this.animatorFingerIn.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - float progress = (float) animation.getAnimatedValue(); - - -// //开始 -// bezierHeight = 0f; -// circleRadius = circleRadiusMin; -// spaceToLine = circleRadiusMin * 2; -// -// //结束 -// bezierHeight = circleRadiusMax * 1.5F; -// circleRadius = circleRadiusMax; -// spaceToLine = 0; - - animInFinshed = (progress >= 0.15F); - txtSelectedBgPaint.setAlpha((int) (255 * (progress - 0.15F))); - - if (progress >= 0.95F) { - textPaint.setColor(colorValueSelected); - } else { - textPaint.setColor(colorValue); - } - - bezierHeight = circleRadiusMax * 1.5F * progress; - circleRadius = circleRadiusMin + (circleRadiusMax - circleRadiusMin) * progress; - spaceToLine = circleRadiusMin * 2 * (1F - progress); - postInvalidate(); - } - }); - - this.animatorFingerOut.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - float progress = (float) animation.getAnimatedValue(); - - animInFinshed = (progress >= 0.15F); - txtSelectedBgPaint.setAlpha((int) (255 * (progress - 0.15F))); - if (progress >= 0.95F) { - textPaint.setColor(colorValueSelected); - } else { - textPaint.setColor(colorValue); - } - - bezierHeight = circleRadiusMax * 1.5F * progress; - circleRadius = circleRadiusMin + (circleRadiusMax - circleRadiusMin) * progress; - spaceToLine = circleRadiusMin * 2 * (1F - progress); - postInvalidate(); - } - }); - } - - - private void initAttr(Context context, AttributeSet attrs) { - if (attrs != null) { - TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.BezierSeekBar); - - this.colorBall = attributes.getColor(R.styleable.BezierSeekBar_bsBar_color_ball, Color.BLACK); - this.colorLine = attributes.getColor(R.styleable.BezierSeekBar_bsBar_color_line, Color.BLACK); - this.colorValue = attributes.getColor(R.styleable.BezierSeekBar_bsBar_color_value, Color.BLACK); - this.colorValueSelected = attributes.getColor(R.styleable.BezierSeekBar_bsBar_color_value_selected, Color.WHITE); - this.colorBgSelected = attributes.getColor(R.styleable.BezierSeekBar_bsBar_color_bg_selected, Color.BLACK); - this.valueMin = attributes.getInteger(R.styleable.BezierSeekBar_bsBar_value_min, 30); - this.valueMax = attributes.getInteger(R.styleable.BezierSeekBar_bsBar_value_max, 150); - this.valueSelected = attributes.getInteger(R.styleable.BezierSeekBar_bsBar_value_selected, 65); - this.unit = attributes.getString(R.styleable.BezierSeekBar_bsBar_unit) + ""; - attributes.recycle(); - } - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - width = this.getMySize(this.diameterDefault, widthMeasureSpec); - - if (getLayoutParams().height == ViewGroup.LayoutParams.WRAP_CONTENT) { - height = this.diameterDefault; - } else { - height = this.getMySize(this.diameterDefault, heightMeasureSpec); - } - setMeasuredDimension(width, height); - - this.fingerXDefault = width * (float) (this.valueSelected - valueMin) / (float) (this.valueMax - this.valueMin); - this.fingerX = this.fingerXDefault; - } - - @Override - protected void onLayout(boolean changed, int left, int top, int right, int bottom) { - super.onLayout(changed, left, top, right, bottom); - - mPaddingStart = getPaddingStart(); - mPaddingEnd = getPaddingEnd(); - mPaddingTop = getPaddingTop(); - mPaddingBottom = getPaddingBottom(); - - bezierHeight = 0; - } - - @Override - protected void onDraw(Canvas canvas) { - super.onDraw(canvas); - - //line - bezierPath.reset(); - bezierPath.moveTo(0, (float) 2 * height / 3); - bezierPath.lineTo(this.fingerX - circleRadiusMax * 2 * 3, (float) 2 * height / 3); - - //bezier - bezierPath.moveTo(this.fingerX - circleRadiusMax * 2 * 3, (float) 2 * height / 3); - bezierPath.cubicTo(this.fingerX - circleRadiusMax * 2 * 2, (float) 2 * height / 3, this.fingerX - circleRadiusMax * 2 * 1, (float) 2 * height / 3 - bezierHeight, this.fingerX, (float) 2 * height / 3 - bezierHeight); - - //bezier - bezierPath.moveTo(this.fingerX, (float) 2 * height / 3 - bezierHeight); - bezierPath.cubicTo(this.fingerX + circleRadiusMax * 2, (float) 2 * height / 3 - bezierHeight, this.fingerX + circleRadiusMax * 2 * 2, (float) 2 * height / 3, this.fingerX + circleRadiusMax * 2 * 3, (float) 2 * height / 3); - - //line - bezierPath.lineTo(width, (float) 2 * height / 3); - canvas.drawPath(bezierPath, bezierPaint); - - //ball - canvas.drawCircle(this.fingerX, (float) 2 * height / 3 + spaceToLine + circleRadius, circleRadius, ballPaint); - - canvas.drawText("" + valueMin, 20F, (float) 2 * height / 3F + textSize, textDownPaint); - canvas.drawText("" + valueMax, width - getTextWidth(textDownPaint, "200") - 20F, (float) 2 * height / 3F + dp2px(getContext(), 12F), textDownPaint); - - String text = valueSelected + unit; - - - float valueX = this.fingerX - getTextWidth(textPaint, text) / 2F - 20F; - float valueXend = fingerX + getTextWidth(textPaint, text) / 2F + 20F; - if (valueX <= 0) { - valueX = 0F; - valueXend = getTextWidth(textPaint, text) + 40F; - } - - if (valueXend >= width) { - valueXend = width; - valueX = width - getTextWidth(textPaint, text) - 40F; - } - if (animInFinshed) { - bgRect.set(valueX, - (float) 2 * height / 3F - bezierHeight * 2 - 30F - getTextHeight(textPaint, text), - valueXend, - (float) 2 * height / 3F - bezierHeight * 2 + 10F); - canvas.drawRoundRect(bgRect, 20F, 20F, txtSelectedBgPaint); - } - - canvas.drawText(text, valueX + 20F, (float) 2 * height / 3F - bezierHeight * 2 - 15F, textPaint); - } - - - @Override - public boolean onTouchEvent(MotionEvent event) { - - switch (event.getAction()) { - case MotionEvent.ACTION_DOWN: - //Log.e("onTouchEvent","ACTION_DOWN"); - fingerX = event.getX(); - if (fingerX < 0F) fingerX = 0F; - if (fingerX > width) fingerX = width; - //在这里执行动画 - this.animatorFingerIn.start(); - break; - - case MotionEvent.ACTION_MOVE: - //Log.e("onTouchEvent","ACTION_MOVE"); - fingerX = event.getX(); - if (fingerX < 0F) fingerX = 0F; - if (fingerX > width) fingerX = width; - postInvalidate(); - break; - - case MotionEvent.ACTION_UP: - //在这里执行动画 - this.animatorFingerOut.start(); - break; - } - - valueSelected = Integer.valueOf(decimalFormat.format(valueMin + (valueMax - valueMin) * fingerX / width)); - - if (selectedListener != null) { - selectedListener.onSelected(valueSelected); - } - - return true; - } - - private int getMySize(int defaultSize, int measureSpec) { - int mySize = defaultSize; - - int mode = MeasureSpec.getMode(measureSpec); - int size = MeasureSpec.getSize(measureSpec); - - switch (mode) { - case MeasureSpec.UNSPECIFIED: - mySize = defaultSize; - break; - case MeasureSpec.AT_MOST: - mySize = size; - break; - case MeasureSpec.EXACTLY: - mySize = size; - break; - } - return mySize; - } - - private float px2dp(Context context, float px) { - final float scale = context.getResources().getDisplayMetrics().density; - return px / scale + 0.5f; - } - - private float dp2px(Context context, float dp) { - - final float scale = context.getResources().getDisplayMetrics().density; - return dp * scale + 0.5f; - } - - private float getTextWidth(Paint paint, String str) { - float iRet = 0; - if (str != null && str.length() > 0) { - int len = str.length(); - float[] widths = new float[len]; - paint.getTextWidths(str, widths); - for (int j = 0; j < len; j++) { - iRet += (float) Math.ceil(widths[j]); - } - } - return iRet; - } - - private float getTextHeight(Paint paint, String str) { - Rect rect = new Rect(); - paint.getTextBounds(str, 0, str.length(), rect); - return (float) rect.height(); - } - - /////////////////////////////////////////////////////////////// - - - public void setValueMax(int valueMax) { - this.valueMax = valueMax; - } - - public void setValueMin(int valueMin) { - this.valueMin = valueMin; - } - - public int getValueMax() { - return valueMax; - } - - public int getValueMin() { - return valueMin; - } - - - public int getColorValue() { - return colorValue; - } - - public void setColorValue(int colorValue) { - this.colorValue = colorValue; - this.textDownPaint.setColor(this.colorValue); - } - - public int getColorValueSelected() { - return colorValueSelected; - } - - public void setColorValueSelected(int colorValueSelected) { - this.colorValueSelected = colorValueSelected; - this.textPaint.setColor(this.colorValue); - } - - public int getColorLine() { - return colorLine; - } - - public void setColorLine(int colorLine) { - this.colorLine = colorLine; - this.bezierPaint.setColor(this.colorLine); - } - - public int getColorBall() { - return colorBall; - } - - public void setColorBgSelected(int colorBgSelected) { - this.colorBgSelected = colorBgSelected; - this.txtSelectedBgPaint.setColor(this.colorBgSelected); - } - - public void setValueSelected(int valueSelected) { - this.valueSelected = valueSelected; - } - - public void setColorBall(int colorBall) { - this.colorBall = colorBall; - this.ballPaint.setColor(this.colorBall); - } - - public void setSelectedListener(OnSelectedListener selectedListener) { - this.selectedListener = selectedListener; - } - - public int getValueSelected(){ - return valueSelected; - } - - public void setUnit(String unit) { - this.unit = unit; - } +package tech.nicesky.bezierseekbar; + +import android.animation.ValueAnimator; +import android.annotation.TargetApi; +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.Point; +import android.graphics.Rect; +import android.graphics.RectF; +import android.graphics.Typeface; +import android.os.Build; +import android.support.annotation.Nullable; +import android.util.AttributeSet; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.view.animation.LinearInterpolator; + +import java.text.DecimalFormat; + +/** + * @author fairytale110 + * @class tech/nicesky/bezierseekbar/BezierSeekBar.java:17 + * @date on 2018/10/12-下午1:53 + * @email fairytale110@foxmail.com + * @description: + */ +public class BezierSeekBar extends View { + + private Context context; + private DecimalFormat decimalFormat; + private int mPaddingStart; + private int mPaddingEnd; + private int mPaddingTop; + private int mPaddingBottom; + + private int width; + private int height; + + /** + * View默认高度 + */ + private int diameterDefault = 300; + + /** + * 曲线弧高度 + */ + private float bezierHeight = 50F; + + private float circleRadiusMin = 15F; + private float circleRadiusMax = circleRadiusMin * 1.5F; + private float circleRadius = circleRadiusMin; + + /** + * 圆与线的垂直距离 + */ + private float spaceToLine = circleRadiusMin * 2F; + + /** + * 触摸点的坐标 + */ + private float fingerX, fingerXDefault, fingerYDefault; + + private float textSelectedSize = 20f; + + private float textSize = 12f; + + private int colorValue, colorValueSelected, colorLine, colorBall, colorBgSelected; + + /** + * 贝塞尔线的path + */ + private Path bezierPath; + + /** + * 曲线画笔 + */ + private Paint bezierPaint, ballPaint, textPaint, textDownPaint; + + /***/ + private Point fingerPoint; + + private Paint txtSelectedBgPaint; + + private RectF bgRect; + + private String unit = "kg"; + private int valueMin, valueMax, valueSelected; + private boolean animInFinshed = false; + + private ValueAnimator animatorFingerIn, animatorFingerOut; + + private OnSelectedListener selectedListener; + + /** + * @param context + */ + + public BezierSeekBar(Context context) { + super(context); + init(context, null); + + } + + public BezierSeekBar(Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + init(context, attrs); + } + + public BezierSeekBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(context, attrs); + } + + + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + public BezierSeekBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + init(context, attrs); + } + + private void init(Context context, AttributeSet attrs) { + this.context = context; + + decimalFormat = new DecimalFormat("#"); +// diameterDefault = (int) dp2px(context, 300); +// +// this.circleRadiusMin = dp2px(context, 12F); +// this.circleRadiusMax = circleRadiusMin * 1.5F; +// this.circleRadius = circleRadiusMin; +// this.spaceToLine = circleRadiusMin *2F; + + textSelectedSize = dp2px(context, 20F); + textSize = dp2px(context, 12F); + + this.valueMax = 200; + this.valueMin = 30; + + this.colorBall = this.colorLine = this.colorValue = Color.BLACK; + this.colorValueSelected = Color.WHITE; + this.fingerX = 100F; + + initAttr(context, attrs); + + this.bgRect = new RectF(); + + this.bezierPaint = new Paint(); + this.bezierPaint.setAntiAlias(true); + this.bezierPaint.setStyle(Paint.Style.STROKE); + this.bezierPaint.setColor(colorLine); + this.bezierPaint.setStrokeWidth(2F); + + this.textPaint = new Paint(); + this.textPaint.setAntiAlias(true); + this.textPaint.setStyle(Paint.Style.FILL); + this.textPaint.setColor(colorValue); + this.textPaint.setStrokeWidth(2F); + Typeface font = Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD); + this.textPaint.setTypeface(font); + this.textPaint.setTextSize(textSelectedSize); + + this.txtSelectedBgPaint = new Paint(); + this.txtSelectedBgPaint.setAntiAlias(true); + this.txtSelectedBgPaint.setColor(colorBgSelected); + this.txtSelectedBgPaint.setStyle(Paint.Style.FILL); + + this.textDownPaint = new Paint(); + this.textDownPaint.setAntiAlias(true); + this.textDownPaint.setStyle(Paint.Style.FILL); + this.textDownPaint.setColor(colorValue); + this.textDownPaint.setStrokeWidth(2F); + this.textDownPaint.setTextSize(textSize); + + this.ballPaint = new Paint(); + this.ballPaint.setAntiAlias(true); + this.ballPaint.setStyle(Paint.Style.FILL); + this.ballPaint.setColor(colorBall); + + this.bezierPath = new Path(); + + this.fingerXDefault = 200f; + this.fingerYDefault = 200f; + + this.bezierPath.moveTo((float) fingerX, (float) 100); + + this.animatorFingerIn = ValueAnimator.ofFloat(0f, 1f); + this.animatorFingerIn.setDuration(200L); + this.animatorFingerIn.setInterpolator(new LinearInterpolator()); + + this.animatorFingerOut = ValueAnimator.ofFloat(1f, 0f); + this.animatorFingerOut.setDuration(200L); + this.animatorFingerOut.setInterpolator(new LinearInterpolator()); + + this.animatorFingerIn.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + float progress = (float) animation.getAnimatedValue(); + + +// //开始 +// bezierHeight = 0f; +// circleRadius = circleRadiusMin; +// spaceToLine = circleRadiusMin * 2; +// +// //结束 +// bezierHeight = circleRadiusMax * 1.5F; +// circleRadius = circleRadiusMax; +// spaceToLine = 0; + + animInFinshed = (progress >= 0.15F); + txtSelectedBgPaint.setAlpha((int) (255 * (progress - 0.15F))); + + if (progress >= 0.95F) { + textPaint.setColor(colorValueSelected); + } else { + textPaint.setColor(colorValue); + } + + bezierHeight = circleRadiusMax * 1.5F * progress; + circleRadius = circleRadiusMin + (circleRadiusMax - circleRadiusMin) * progress; + spaceToLine = circleRadiusMin * 2 * (1F - progress); + postInvalidate(); + } + }); + + this.animatorFingerOut.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + float progress = (float) animation.getAnimatedValue(); + + animInFinshed = (progress >= 0.15F); + txtSelectedBgPaint.setAlpha((int) (255 * (progress - 0.15F))); + if (progress >= 0.95F) { + textPaint.setColor(colorValueSelected); + } else { + textPaint.setColor(colorValue); + } + + bezierHeight = circleRadiusMax * 1.5F * progress; + circleRadius = circleRadiusMin + (circleRadiusMax - circleRadiusMin) * progress; + spaceToLine = circleRadiusMin * 2 * (1F - progress); + postInvalidate(); + } + }); + } + + + private void initAttr(Context context, AttributeSet attrs) { + if (attrs != null) { + TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.BezierSeekBar); + + this.colorBall = attributes.getColor(R.styleable.BezierSeekBar_bsBar_color_ball, Color.BLACK); + this.colorLine = attributes.getColor(R.styleable.BezierSeekBar_bsBar_color_line, Color.BLACK); + this.colorValue = attributes.getColor(R.styleable.BezierSeekBar_bsBar_color_value, Color.BLACK); + this.colorValueSelected = attributes.getColor(R.styleable.BezierSeekBar_bsBar_color_value_selected, Color.WHITE); + this.colorBgSelected = attributes.getColor(R.styleable.BezierSeekBar_bsBar_color_bg_selected, Color.BLACK); + this.valueMin = attributes.getInteger(R.styleable.BezierSeekBar_bsBar_value_min, 30); + this.valueMax = attributes.getInteger(R.styleable.BezierSeekBar_bsBar_value_max, 150); + this.valueSelected = attributes.getInteger(R.styleable.BezierSeekBar_bsBar_value_selected, 65); + this.unit = attributes.getString(R.styleable.BezierSeekBar_bsBar_unit) + ""; + attributes.recycle(); + } + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + width = this.getMySize(this.diameterDefault, widthMeasureSpec); + + if (getLayoutParams().height == ViewGroup.LayoutParams.WRAP_CONTENT) { + height = this.diameterDefault; + } else { + height = this.getMySize(this.diameterDefault, heightMeasureSpec); + } + setMeasuredDimension(width, height); + + this.fingerXDefault = width * (float) (this.valueSelected - valueMin) / (float) (this.valueMax - this.valueMin); + this.fingerX = this.fingerXDefault; + } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + super.onLayout(changed, left, top, right, bottom); + + mPaddingStart = getPaddingStart(); + mPaddingEnd = getPaddingEnd(); + mPaddingTop = getPaddingTop(); + mPaddingBottom = getPaddingBottom(); + + bezierHeight = 0; + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + + //line + bezierPath.reset(); + bezierPath.moveTo(0, (float) 2 * height / 3); + bezierPath.lineTo(this.fingerX - circleRadiusMax * 2 * 3, (float) 2 * height / 3); + + //bezier + bezierPath.moveTo(this.fingerX - circleRadiusMax * 2 * 3, (float) 2 * height / 3); + bezierPath.cubicTo(this.fingerX - circleRadiusMax * 2 * 2, (float) 2 * height / 3, this.fingerX - circleRadiusMax * 2 * 1, (float) 2 * height / 3 - bezierHeight, this.fingerX, (float) 2 * height / 3 - bezierHeight); + + //bezier + bezierPath.moveTo(this.fingerX, (float) 2 * height / 3 - bezierHeight); + bezierPath.cubicTo(this.fingerX + circleRadiusMax * 2, (float) 2 * height / 3 - bezierHeight, this.fingerX + circleRadiusMax * 2 * 2, (float) 2 * height / 3, this.fingerX + circleRadiusMax * 2 * 3, (float) 2 * height / 3); + + //line + bezierPath.lineTo(width, (float) 2 * height / 3); + canvas.drawPath(bezierPath, bezierPaint); + + //ball + canvas.drawCircle(this.fingerX, (float) 2 * height / 3 + spaceToLine + circleRadius, circleRadius, ballPaint); + + canvas.drawText("" + valueMin, 20F, (float) 2 * height / 3F + textSize, textDownPaint); + canvas.drawText("" + valueMax, width - getTextWidth(textDownPaint, "200") - 20F, (float) 2 * height / 3F + dp2px(getContext(), 12F), textDownPaint); + + String text = valueSelected + unit; + + + float valueX = this.fingerX - getTextWidth(textPaint, text) / 2F - 20F; + float valueXend = fingerX + getTextWidth(textPaint, text) / 2F + 20F; + if (valueX <= 0) { + valueX = 0F; + valueXend = getTextWidth(textPaint, text) + 40F; + } + + if (valueXend >= width) { + valueXend = width; + valueX = width - getTextWidth(textPaint, text) - 40F; + } + if (animInFinshed) { + bgRect.set(valueX, + (float) 2 * height / 3F - bezierHeight * 2 - 30F - getTextHeight(textPaint, text), + valueXend, + (float) 2 * height / 3F - bezierHeight * 2 + 10F); + canvas.drawRoundRect(bgRect, 20F, 20F, txtSelectedBgPaint); + } + + canvas.drawText(text, valueX + 20F, (float) 2 * height / 3F - bezierHeight * 2 - 15F, textPaint); + } + + + @Override + public boolean onTouchEvent(MotionEvent event) { + + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //Log.e("onTouchEvent","ACTION_DOWN"); + fingerX = event.getX(); + if (fingerX < 0F) fingerX = 0F; + if (fingerX > width) fingerX = width; + //在这里执行动画 + this.animatorFingerIn.start(); + break; + + case MotionEvent.ACTION_MOVE: + //Log.e("onTouchEvent","ACTION_MOVE"); + fingerX = event.getX(); + if (fingerX < 0F) fingerX = 0F; + if (fingerX > width) fingerX = width; + postInvalidate(); + break; + + case MotionEvent.ACTION_UP: + //在这里执行动画 + this.animatorFingerOut.start(); + break; + } + + valueSelected = Integer.valueOf(decimalFormat.format(valueMin + (valueMax - valueMin) * fingerX / width)); + + if (selectedListener != null) { + selectedListener.onSelected(valueSelected); + } + + return true; + } + + private int getMySize(int defaultSize, int measureSpec) { + int mySize = defaultSize; + + int mode = MeasureSpec.getMode(measureSpec); + int size = MeasureSpec.getSize(measureSpec); + + switch (mode) { + case MeasureSpec.UNSPECIFIED: + mySize = defaultSize; + break; + case MeasureSpec.AT_MOST: + mySize = size; + break; + case MeasureSpec.EXACTLY: + mySize = size; + break; + } + return mySize; + } + + private float px2dp(Context context, float px) { + final float scale = context.getResources().getDisplayMetrics().density; + return px / scale + 0.5f; + } + + private float dp2px(Context context, float dp) { + + final float scale = context.getResources().getDisplayMetrics().density; + return dp * scale + 0.5f; + } + + private float getTextWidth(Paint paint, String str) { + float iRet = 0; + if (str != null && str.length() > 0) { + int len = str.length(); + float[] widths = new float[len]; + paint.getTextWidths(str, widths); + for (int j = 0; j < len; j++) { + iRet += (float) Math.ceil(widths[j]); + } + } + return iRet; + } + + private float getTextHeight(Paint paint, String str) { + Rect rect = new Rect(); + paint.getTextBounds(str, 0, str.length(), rect); + return (float) rect.height(); + } + + /////////////////////////////////////////////////////////////// + + + public void setValueMax(int valueMax) { + this.valueMax = valueMax; + } + + public void setValueMin(int valueMin) { + this.valueMin = valueMin; + } + + public int getValueMax() { + return valueMax; + } + + public int getValueMin() { + return valueMin; + } + + + public int getColorValue() { + return colorValue; + } + + public void setColorValue(int colorValue) { + this.colorValue = colorValue; + this.textDownPaint.setColor(this.colorValue); + } + + public int getColorValueSelected() { + return colorValueSelected; + } + + public void setColorValueSelected(int colorValueSelected) { + this.colorValueSelected = colorValueSelected; + this.textPaint.setColor(this.colorValue); + } + + public int getColorLine() { + return colorLine; + } + + public void setColorLine(int colorLine) { + this.colorLine = colorLine; + this.bezierPaint.setColor(this.colorLine); + } + + public int getColorBall() { + return colorBall; + } + + public void setColorBgSelected(int colorBgSelected) { + this.colorBgSelected = colorBgSelected; + this.txtSelectedBgPaint.setColor(this.colorBgSelected); + } + + public void setValueSelected(int valueSelected) { + this.valueSelected = valueSelected; + this.fingerXDefault = width * (float) (this.valueSelected - valueMin) / (float) (this.valueMax - this.valueMin); + this.fingerX = this.fingerXDefault; + postInvalidate(); + } + + public void setColorBall(int colorBall) { + this.colorBall = colorBall; + this.ballPaint.setColor(this.colorBall); + } + + public void setSelectedListener(OnSelectedListener selectedListener) { + this.selectedListener = selectedListener; + } + + public int getValueSelected(){ + return valueSelected; + } + + public void setUnit(String unit) { + this.unit = unit; + } } \ No newline at end of file