├── wave_library
├── .gitignore
├── src
│ └── main
│ │ ├── AndroidManifest.xml
│ │ ├── res
│ │ └── values
│ │ │ └── attr.xml
│ │ └── java
│ │ └── com
│ │ └── john
│ │ └── waveview
│ │ ├── Solid.java
│ │ ├── WaveView.java
│ │ └── Wave.java
├── build.gradle
└── proguard-rules.pro
├── settings.gradle
├── img.gif
├── progress.gif
├── raw
├── screenshot1.png
├── screenshot2.png
├── screenshot3.png
└── screenshot4.png
├── sample
├── ic_launcher-web.png
├── .settings
│ ├── org.eclipse.jdt.ui.prefs
│ └── org.eclipse.jdt.core.prefs
├── res
│ ├── drawable-xxxhdpi
│ │ ├── bg.png
│ │ ├── home_bg.png
│ │ ├── home_msg.png
│ │ ├── home_net.png
│ │ ├── home_num.png
│ │ ├── home_pay.png
│ │ ├── menu_vip.png
│ │ ├── home_arrow.png
│ │ ├── home_cheap.png
│ │ ├── home_find.png
│ │ ├── home_menu.png
│ │ ├── home_order.png
│ │ ├── home_park.png
│ │ ├── home_action.png
│ │ ├── home_integral.png
│ │ ├── home_sign_ok.png
│ │ ├── ic_launcher.png
│ │ ├── menu_setting.png
│ │ ├── dialog_bar_code.png
│ │ ├── dialog_qr_code.png
│ │ ├── dialog_sign_bg.png
│ │ └── home_sign_defaut.png
│ ├── drawable-hdpi
│ │ └── ic_launcher.png
│ ├── drawable-mdpi
│ │ └── ic_launcher.png
│ ├── drawable-xhdpi
│ │ └── ic_launcher.png
│ ├── drawable-xxhdpi
│ │ └── ic_launcher.png
│ ├── values-sw600dp
│ │ └── dimens.xml
│ ├── values
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── theme.xml
│ ├── anim
│ │ ├── anim_marquee_in.xml
│ │ └── anim_marquee_out.xml
│ ├── drawable
│ │ ├── barcode_dialog_bg_shape.xml
│ │ ├── qrcode_dialog_bg_shape.xml
│ │ ├── sign_dialog_btn_shape.xml
│ │ └── select_item_shape.xml
│ ├── menu
│ │ └── circular_progress_bar_sample.xml
│ ├── values-sw720dp-land
│ │ └── dimens.xml
│ ├── values-v11
│ │ └── styles.xml
│ ├── values-v14
│ │ └── styles.xml
│ └── layout
│ │ ├── layout_roll_msg.xml
│ │ ├── item_menu_layout.xml
│ │ ├── layout_sign_dialog.xml
│ │ ├── layout_qrcode_dialog.xml
│ │ ├── layout_menu.xml
│ │ ├── activity_main.xml
│ │ └── activity_home.xml
├── libs
│ └── nineoldandroids-2.4.0.jar
├── gradle.properties
├── project.properties
├── build.gradle
├── src
│ └── com
│ │ └── pascalwelsch
│ │ └── circularprogressbarsample
│ │ ├── QRCodeDialog.java
│ │ ├── base
│ │ ├── ViewHolder.java
│ │ └── BaseAdapter.java
│ │ ├── MenuBean.java
│ │ ├── HomeMuneAdapter.java
│ │ ├── MenuLeftFragment.java
│ │ ├── SignDialog.java
│ │ ├── HomeActivity.java
│ │ └── CircularProgressBarSample.java
├── proguard-project.txt
└── AndroidManifest.xml
├── library
├── gradle.properties
├── res
│ ├── drawable-xxxhdpi
│ │ ├── bg.png
│ │ ├── big_circle.png
│ │ └── ic_launcher.png
│ └── values
│ │ ├── attrs.xml
│ │ └── styles.xml
├── build.gradle
├── AndroidManifest.xml
├── project.properties
├── proguard-project.txt
├── src
│ └── com
│ │ └── pascalwelsch
│ │ └── holocircularprogressbar
│ │ ├── DensityUtils.java
│ │ └── HoloCircularProgressBar.java
└── .settings
│ └── org.eclipse.jdt.ui.prefs
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── README.md
├── .gitignore
├── gradlew.bat
└── gradlew
/wave_library/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':library', ':wave_library'
2 | include ':sample'
3 |
--------------------------------------------------------------------------------
/img.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XHiStone/android-HoloCircularProgressBar-master/HEAD/img.gif
--------------------------------------------------------------------------------
/progress.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XHiStone/android-HoloCircularProgressBar-master/HEAD/progress.gif
--------------------------------------------------------------------------------
/raw/screenshot1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XHiStone/android-HoloCircularProgressBar-master/HEAD/raw/screenshot1.png
--------------------------------------------------------------------------------
/raw/screenshot2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XHiStone/android-HoloCircularProgressBar-master/HEAD/raw/screenshot2.png
--------------------------------------------------------------------------------
/raw/screenshot3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XHiStone/android-HoloCircularProgressBar-master/HEAD/raw/screenshot3.png
--------------------------------------------------------------------------------
/raw/screenshot4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XHiStone/android-HoloCircularProgressBar-master/HEAD/raw/screenshot4.png
--------------------------------------------------------------------------------
/sample/ic_launcher-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XHiStone/android-HoloCircularProgressBar-master/HEAD/sample/ic_launcher-web.png
--------------------------------------------------------------------------------
/sample/.settings/org.eclipse.jdt.ui.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | formatter_profile=_Android
3 | formatter_settings_version=12
4 |
--------------------------------------------------------------------------------
/library/gradle.properties:
--------------------------------------------------------------------------------
1 | ARTIFACT_ID=library
2 | NAME=HoloCircularProgressBar
3 | PACKAGING=aar
4 | DESCRIPTION=HoloCircularProgressBar library
5 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XHiStone/android-HoloCircularProgressBar-master/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/library/res/drawable-xxxhdpi/bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XHiStone/android-HoloCircularProgressBar-master/HEAD/library/res/drawable-xxxhdpi/bg.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxxhdpi/bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XHiStone/android-HoloCircularProgressBar-master/HEAD/sample/res/drawable-xxxhdpi/bg.png
--------------------------------------------------------------------------------
/sample/libs/nineoldandroids-2.4.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XHiStone/android-HoloCircularProgressBar-master/HEAD/sample/libs/nineoldandroids-2.4.0.jar
--------------------------------------------------------------------------------
/sample/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XHiStone/android-HoloCircularProgressBar-master/HEAD/sample/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XHiStone/android-HoloCircularProgressBar-master/HEAD/sample/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxxhdpi/home_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XHiStone/android-HoloCircularProgressBar-master/HEAD/sample/res/drawable-xxxhdpi/home_bg.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxxhdpi/home_msg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XHiStone/android-HoloCircularProgressBar-master/HEAD/sample/res/drawable-xxxhdpi/home_msg.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxxhdpi/home_net.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XHiStone/android-HoloCircularProgressBar-master/HEAD/sample/res/drawable-xxxhdpi/home_net.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxxhdpi/home_num.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XHiStone/android-HoloCircularProgressBar-master/HEAD/sample/res/drawable-xxxhdpi/home_num.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxxhdpi/home_pay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XHiStone/android-HoloCircularProgressBar-master/HEAD/sample/res/drawable-xxxhdpi/home_pay.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxxhdpi/menu_vip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XHiStone/android-HoloCircularProgressBar-master/HEAD/sample/res/drawable-xxxhdpi/menu_vip.png
--------------------------------------------------------------------------------
/sample/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XHiStone/android-HoloCircularProgressBar-master/HEAD/sample/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XHiStone/android-HoloCircularProgressBar-master/HEAD/sample/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxxhdpi/home_arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XHiStone/android-HoloCircularProgressBar-master/HEAD/sample/res/drawable-xxxhdpi/home_arrow.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxxhdpi/home_cheap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XHiStone/android-HoloCircularProgressBar-master/HEAD/sample/res/drawable-xxxhdpi/home_cheap.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxxhdpi/home_find.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XHiStone/android-HoloCircularProgressBar-master/HEAD/sample/res/drawable-xxxhdpi/home_find.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxxhdpi/home_menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XHiStone/android-HoloCircularProgressBar-master/HEAD/sample/res/drawable-xxxhdpi/home_menu.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxxhdpi/home_order.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XHiStone/android-HoloCircularProgressBar-master/HEAD/sample/res/drawable-xxxhdpi/home_order.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxxhdpi/home_park.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XHiStone/android-HoloCircularProgressBar-master/HEAD/sample/res/drawable-xxxhdpi/home_park.png
--------------------------------------------------------------------------------
/library/res/drawable-xxxhdpi/big_circle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XHiStone/android-HoloCircularProgressBar-master/HEAD/library/res/drawable-xxxhdpi/big_circle.png
--------------------------------------------------------------------------------
/library/res/drawable-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XHiStone/android-HoloCircularProgressBar-master/HEAD/library/res/drawable-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxxhdpi/home_action.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XHiStone/android-HoloCircularProgressBar-master/HEAD/sample/res/drawable-xxxhdpi/home_action.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxxhdpi/home_integral.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XHiStone/android-HoloCircularProgressBar-master/HEAD/sample/res/drawable-xxxhdpi/home_integral.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxxhdpi/home_sign_ok.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XHiStone/android-HoloCircularProgressBar-master/HEAD/sample/res/drawable-xxxhdpi/home_sign_ok.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XHiStone/android-HoloCircularProgressBar-master/HEAD/sample/res/drawable-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxxhdpi/menu_setting.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XHiStone/android-HoloCircularProgressBar-master/HEAD/sample/res/drawable-xxxhdpi/menu_setting.png
--------------------------------------------------------------------------------
/sample/gradle.properties:
--------------------------------------------------------------------------------
1 | ARTIFACT_ID=sample
2 | NAME=HoloCircularProgressBar-sample
3 | PACKAGING=apk
4 | DESCRIPTION=Sample application for HoloCircularProgressBar library
5 |
--------------------------------------------------------------------------------
/sample/res/drawable-xxxhdpi/dialog_bar_code.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XHiStone/android-HoloCircularProgressBar-master/HEAD/sample/res/drawable-xxxhdpi/dialog_bar_code.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxxhdpi/dialog_qr_code.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XHiStone/android-HoloCircularProgressBar-master/HEAD/sample/res/drawable-xxxhdpi/dialog_qr_code.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxxhdpi/dialog_sign_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XHiStone/android-HoloCircularProgressBar-master/HEAD/sample/res/drawable-xxxhdpi/dialog_sign_bg.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxxhdpi/home_sign_defaut.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XHiStone/android-HoloCircularProgressBar-master/HEAD/sample/res/drawable-xxxhdpi/home_sign_defaut.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # android-HoloCircularProgressBar-master
2 | 动态积分圆进度条
3 | 
4 |
--------------------------------------------------------------------------------
/wave_library/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
92 | * {@link #computeInsets(int, int)} 93 | */ 94 | private int mGravity = Gravity.LEFT; 95 | 96 | /** 97 | * The Horizontal inset calcualted in {@link #computeInsets(int, int)} depends on {@link 98 | * #mGravity}. 99 | */ 100 | private int mHorizontalInset = 0; 101 | 102 | /** 103 | * true if not all properties are set. then the view isn't drawn and there are no errors in the 104 | * LayoutEditor 105 | */ 106 | private boolean mIsInitializing = true; 107 | 108 | /** 109 | * flag if the marker should be visible 110 | */ 111 | private boolean mIsMarkerEnabled = false; 112 | 113 | /** 114 | * indicates if the thumb is visible 115 | */ 116 | private boolean mIsThumbEnabled = true; 117 | 118 | /** 119 | * The Marker color paint. 120 | */ 121 | private Paint mMarkerColorPaint; 122 | 123 | private TextPaint mMarkerTextPaint; 124 | 125 | /** 126 | * The Marker progress. 127 | */ 128 | private float mMarkerProgress = 0.0f; 129 | 130 | /** 131 | * the overdraw is true if the progress is over 1.0. 132 | */ 133 | private boolean mOverrdraw = false; 134 | 135 | /** 136 | * The current progress. 137 | */ 138 | private float mProgress = 0.3f; 139 | 140 | /** 141 | * The color of the progress background. 142 | */ 143 | private int mProgressBackgroundColor; 144 | 145 | /** 146 | * the color of the progress. 147 | */ 148 | private int mProgressColor; 149 | 150 | private int mMarkerProgressColor; 151 | 152 | /** 153 | * paint for the progress. 154 | */ 155 | private Paint mProgressColorPaint; 156 | 157 | /** 158 | * Radius of the circle 159 | *
160 | *
Note: (Re)calculated in {@link #onMeasure(int, int)}.
161 | */ 162 | private float mRadius; 163 | 164 | /** 165 | * The Thumb color paint. 166 | */ 167 | private Paint mThumbColorPaint; 168 | private Paint mThumbCirclePaint; 169 | private TextPaint mThumbTextPaint; 170 | private Paint mThumbBitmapPaint; 171 | private int mThumbStrokeColor; 172 | private String mThumbStrokeText; 173 | private float mThumbStrokeTextSize; 174 | /** 175 | * The Thumb pos x. 176 | *177 | * Care. the position is not the position of the rotated thumb. The position is only calculated 178 | * in {@link #onMeasure(int, int)} 179 | */ 180 | private float mThumbPosX; 181 | 182 | /** 183 | * The Thumb pos y. 184 | *
185 | * Care. the position is not the position of the rotated thumb. The position is only calculated 186 | * in {@link #onMeasure(int, int)} 187 | */ 188 | private float mThumbPosY; 189 | 190 | /** 191 | * The pointer width (in pixels). 192 | */ 193 | private int mThumbRadius = 20; 194 | 195 | /** 196 | * The Translation offset x which gives us the ability to use our own coordinates system. 197 | */ 198 | private float mTranslationOffsetX; 199 | 200 | /** 201 | * The Translation offset y which gives us the ability to use our own coordinates system. 202 | */ 203 | private float mTranslationOffsetY; 204 | 205 | /** 206 | * The Vertical inset calcualted in {@link #computeInsets(int, int)} depends on {@link 207 | * #mGravity}.. 208 | */ 209 | private int mVerticalInset = 0; 210 | 211 | private String mMarkerProgressText; 212 | private float mMarkerProgressTextSize; 213 | private int mMarkerStrokeMove; 214 | private int mThumbStrokeMove; 215 | 216 | 217 | /** 218 | * Instantiates a new holo circular progress bar. 219 | * 220 | * @param context the context 221 | */ 222 | public HoloCircularProgressBar(final Context context) { 223 | this(context, null); 224 | } 225 | 226 | /** 227 | * Instantiates a new holo circular progress bar. 228 | * 229 | * @param context the context 230 | * @param attrs the attrs 231 | */ 232 | public HoloCircularProgressBar(final Context context, final AttributeSet attrs) { 233 | this(context, attrs, R.attr.circularProgressBarStyle); 234 | } 235 | 236 | /** 237 | * Instantiates a new holo circular progress bar. 238 | * 239 | * @param context the context 240 | * @param attrs the attrs 241 | * @param defStyle the def style 242 | */ 243 | public HoloCircularProgressBar(final Context context, final AttributeSet attrs, 244 | final int defStyle) { 245 | super(context, attrs, defStyle); 246 | 247 | // load the styled attributes and set their properties 248 | final TypedArray attributes = context 249 | .obtainStyledAttributes(attrs, R.styleable.HoloCircularProgressBar, 250 | defStyle, 0); 251 | 252 | if (attributes != null) { 253 | try { 254 | 255 | setProgressBackgroundColor(attributes 256 | .getColor(R.styleable.HoloCircularProgressBar_progress_background_color, 257 | Color.GRAY)); 258 | setProgress( 259 | attributes.getFloat(R.styleable.HoloCircularProgressBar_progress, 0.0f)); 260 | setProgressColor(attributes 261 | .getColor(R.styleable.HoloCircularProgressBar_progress_color, Color.CYAN)); 262 | 263 | setMarkerEnabled(attributes 264 | .getBoolean(R.styleable.HoloCircularProgressBar_marker_visible, true)); 265 | setMarkerProgress( 266 | attributes.getFloat(R.styleable.HoloCircularProgressBar_marker_progress, 267 | 0.0f)); 268 | setMarkerProgressText(attributes.getString(R.styleable.HoloCircularProgressBar_marker_progress_text)); 269 | setMarkerProgressTextSize(attributes.getDimension(R.styleable.HoloCircularProgressBar_marker_progress_textSize, 12)); 270 | setMarkerProgressColor(attributes.getColor(R.styleable.HoloCircularProgressBar_marker_progress_color, Color.GRAY)); 271 | 272 | setWheelSize((int) attributes 273 | .getDimension(R.styleable.HoloCircularProgressBar_stroke_width, 10)); 274 | setThumbEnabled(attributes 275 | .getBoolean(R.styleable.HoloCircularProgressBar_thumb_visible, true)); 276 | setThumbStrokeColor(attributes.getColor(R.styleable.HoloCircularProgressBar_thumb_stroke_color, Color.GRAY)); 277 | setThumbStrokeText(attributes.getString(R.styleable.HoloCircularProgressBar_thumb_stroke_text)); 278 | setThumbStrokeTextSize(attributes.getDimension(R.styleable.HoloCircularProgressBar_thumb_stroke_textSize, 16)); 279 | mGravity = attributes 280 | .getInt(R.styleable.HoloCircularProgressBar_android_gravity, 281 | Gravity.CENTER); 282 | // bitmap = ((BitmapDrawable) getResources().getDrawable(R.drawable.big_circle)).getBitmap(); 283 | } finally { 284 | // make sure recycle is always called. 285 | attributes.recycle(); 286 | } 287 | } 288 | 289 | mThumbRadius = mCircleStrokeWidth * 2; 290 | 291 | updateBackgroundColor(); 292 | 293 | updateMarkerColor(); 294 | 295 | updateProgressColor(); 296 | 297 | // the view has now all properties and can be drawn 298 | mIsInitializing = false; 299 | 300 | } 301 | 302 | private void setThumbStrokeTextSize(float dimension) { 303 | mThumbStrokeTextSize = dimension; 304 | } 305 | 306 | public void setThumbStrokeText(String string) { 307 | if (!TextUtils.isEmpty(string)) { 308 | mThumbStrokeText = string; 309 | } else { 310 | mThumbStrokeText = ""; 311 | } 312 | } 313 | 314 | private void setThumbStrokeColor(int color) { 315 | mThumbStrokeColor = color; 316 | } 317 | 318 | private void setMarkerProgressTextSize(float dimension) { 319 | mMarkerProgressTextSize = dimension; 320 | } 321 | 322 | public void setMarkerProgressText(String string) { 323 | if (!TextUtils.isEmpty(string)) { 324 | mMarkerProgressText = string; 325 | } else { 326 | mMarkerProgressText = ""; 327 | } 328 | } 329 | 330 | @Override 331 | protected void onDraw(final Canvas canvas) { 332 | 333 | // All of our positions are using our internal coordinate system. 334 | // Instead of translating 335 | // them we let Canvas do the work for us. 336 | canvas.translate(mTranslationOffsetX, mTranslationOffsetY); 337 | 338 | final float progressRotation = getCurrentRotation(); 339 | 340 | // draw the background 341 | if (!mOverrdraw) { 342 | canvas.drawArc(mCircleBounds, 270, -(360 - progressRotation), false, 343 | mBackgroundColorPaint); 344 | } 345 | 346 | // draw the progress or a full circle if overdraw is true 347 | canvas.drawArc(mCircleBounds, 270, mOverrdraw ? 360 : progressRotation, false, 348 | mProgressColorPaint); 349 | 350 | 351 | // draw the marker at the correct rotated position 352 | if (mIsMarkerEnabled) { 353 | final float markerRotation = getMarkerRotation(); 354 | 355 | canvas.save(); 356 | canvas.rotate(markerRotation - 90); 357 | if (markerRotation < 180) { 358 | canvas.rotate(0, mThumbPosX, mThumbPosY); 359 | mMarkerStrokeMove = -mCircleStrokeWidth; 360 | } else { 361 | canvas.rotate(180, mThumbPosX, mThumbPosY); 362 | mMarkerStrokeMove = +mCircleStrokeWidth; 363 | } 364 | // canvas.drawLine((float) (mThumbPosX + mThumbRadius / 2 * 1.4), mThumbPosY, 365 | // (float) (mThumbPosX - mThumbRadius / 2 * 1.4), mThumbPosY, mMarkerColorPaint); 366 | mMarkerColorPaint.setColor(mMarkerProgressColor); 367 | canvas.drawCircle(mThumbPosX, mThumbPosY, (float) mCircleStrokeWidth, mMarkerColorPaint); 368 | canvas.drawText(mMarkerProgressText, mThumbPosX + mMarkerStrokeMove * 3.5f, mThumbPosY, mMarkerTextPaint); 369 | canvas.restore(); 370 | } 371 | 372 | if (isThumbEnabled()) { 373 | // draw the thumb square at the correct rotated position 374 | canvas.save(); 375 | canvas.rotate(progressRotation - 90); 376 | if (progressRotation < 180) { 377 | // rotate the square by 45 degrees 378 | canvas.rotate(90 - progressRotation, mThumbPosX, mThumbPosY); 379 | mThumbStrokeTextSize = -mCircleStrokeWidth; 380 | } else { 381 | // rotate the square by 45 degrees 382 | canvas.rotate(90 + 360 - progressRotation, mThumbPosX, mThumbPosY); 383 | mThumbStrokeTextSize = +mCircleStrokeWidth; 384 | } 385 | // mSquareRect.left = mThumbPosX - mThumbRadius / 3; 386 | // mSquareRect.right = mThumbPosX + mThumbRadius / 3; 387 | // mSquareRect.top = mThumbPosY - mThumbRadius / 3; 388 | // mSquareRect.bottom = mThumbPosY + mThumbRadius / 3; 389 | // canvas.drawRect(mSquareRect, mThumbColorPaint); 390 | canvas.drawCircle(mThumbPosX, mThumbPosY, (float) mCircleStrokeWidth * 2.5f, mThumbColorPaint); 391 | canvas.drawCircle(mThumbPosX, mThumbPosY, (float) mCircleStrokeWidth * 2.5f, mThumbCirclePaint); 392 | canvas.drawText(mThumbStrokeText, mThumbPosX - mThumbStrokeTextSize * 8f, mThumbPosY + mCircleStrokeWidth * 2, mThumbTextPaint); 393 | // canvas.drawBitmap(bitmap, mThumbPosX - 60, mThumbPosY - 60, mThumbBitmapPaint); 394 | canvas.restore(); 395 | } 396 | } 397 | 398 | @Override 399 | protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) { 400 | 401 | final int height = getDefaultSize( 402 | getSuggestedMinimumHeight() + getPaddingTop() + getPaddingBottom(), 403 | heightMeasureSpec); 404 | final int width = getDefaultSize( 405 | getSuggestedMinimumWidth() + getPaddingLeft() + getPaddingRight(), 406 | widthMeasureSpec); 407 | 408 | final int diameter; 409 | if (heightMeasureSpec == MeasureSpec.UNSPECIFIED) { 410 | // ScrollView 411 | diameter = width; 412 | computeInsets(0, 0); 413 | } else if (widthMeasureSpec == MeasureSpec.UNSPECIFIED) { 414 | // HorizontalScrollView 415 | diameter = height; 416 | computeInsets(0, 0); 417 | } else { 418 | // Default 419 | diameter = Math.min(width, height); 420 | computeInsets(width - diameter, height - diameter); 421 | } 422 | 423 | setMeasuredDimension(width, height); 424 | 425 | final float halfWidth = diameter * 0.5f; 426 | 427 | // width of the drawed circle (+ the drawedThumb) 428 | final float drawedWith; 429 | if (isThumbEnabled()) { 430 | drawedWith = mThumbRadius * (5f / 6f); 431 | } else if (isMarkerEnabled()) { 432 | drawedWith = mCircleStrokeWidth * 1.4f; 433 | } else { 434 | drawedWith = mCircleStrokeWidth / 2f; 435 | } 436 | 437 | // -0.5f for pixel perfect fit inside the viewbounds 438 | mRadius = halfWidth - drawedWith - DensityUtils.dp2px(getContext(), 35); 439 | 440 | mCircleBounds.set(-mRadius, -mRadius, mRadius, mRadius); 441 | 442 | 443 | mThumbPosX = (float) (mRadius * Math.cos(0)); 444 | mThumbPosY = (float) (mRadius * Math.sin(0)); 445 | 446 | mTranslationOffsetX = width * 0.5f; 447 | mTranslationOffsetY = halfWidth - DensityUtils.dp2px(getContext(), 25); 448 | 449 | } 450 | 451 | @Override 452 | protected void onRestoreInstanceState(final Parcelable state) { 453 | if (state instanceof Bundle) { 454 | final Bundle bundle = (Bundle) state; 455 | setProgress(bundle.getFloat(INSTANCE_STATE_PROGRESS)); 456 | setMarkerProgress(bundle.getFloat(INSTANCE_STATE_MARKER_PROGRESS)); 457 | 458 | final int progressColor = bundle.getInt(INSTANCE_STATE_PROGRESS_COLOR); 459 | if (progressColor != mProgressColor) { 460 | mProgressColor = progressColor; 461 | updateProgressColor(); 462 | } 463 | 464 | final int progressBackgroundColor = bundle 465 | .getInt(INSTANCE_STATE_PROGRESS_BACKGROUND_COLOR); 466 | if (progressBackgroundColor != mProgressBackgroundColor) { 467 | mProgressBackgroundColor = progressBackgroundColor; 468 | updateBackgroundColor(); 469 | } 470 | 471 | mIsThumbEnabled = bundle.getBoolean(INSTANCE_STATE_THUMB_VISIBLE); 472 | 473 | mIsMarkerEnabled = bundle.getBoolean(INSTANCE_STATE_MARKER_VISIBLE); 474 | 475 | super.onRestoreInstanceState(bundle.getParcelable(INSTANCE_STATE_SAVEDSTATE)); 476 | return; 477 | } 478 | 479 | super.onRestoreInstanceState(state); 480 | } 481 | 482 | @Override 483 | protected Parcelable onSaveInstanceState() { 484 | final Bundle bundle = new Bundle(); 485 | bundle.putParcelable(INSTANCE_STATE_SAVEDSTATE, super.onSaveInstanceState()); 486 | bundle.putFloat(INSTANCE_STATE_PROGRESS, mProgress); 487 | bundle.putFloat(INSTANCE_STATE_MARKER_PROGRESS, mMarkerProgress); 488 | bundle.putInt(INSTANCE_STATE_PROGRESS_COLOR, mProgressColor); 489 | bundle.putInt(INSTANCE_STATE_PROGRESS_BACKGROUND_COLOR, mProgressBackgroundColor); 490 | bundle.putBoolean(INSTANCE_STATE_THUMB_VISIBLE, mIsThumbEnabled); 491 | bundle.putBoolean(INSTANCE_STATE_MARKER_VISIBLE, mIsMarkerEnabled); 492 | return bundle; 493 | } 494 | 495 | public int getCircleStrokeWidth() { 496 | return mCircleStrokeWidth; 497 | } 498 | 499 | /** 500 | * similar to {@link #getProgress} 501 | */ 502 | public float getMarkerProgress() { 503 | return mMarkerProgress; 504 | } 505 | 506 | /** 507 | * gives the current progress of the ProgressBar. Value between 0..1 if you set the progress to 508 | * >1 you'll get progress % 1 as return value 509 | * 510 | * @return the progress 511 | */ 512 | public float getProgress() { 513 | return mProgress; 514 | } 515 | 516 | /** 517 | * Gets the progress color. 518 | * 519 | * @return the progress color 520 | */ 521 | public int getProgressColor() { 522 | return mProgressColor; 523 | } 524 | 525 | /** 526 | * @return true if the marker is visible 527 | */ 528 | public boolean isMarkerEnabled() { 529 | return mIsMarkerEnabled; 530 | } 531 | 532 | /** 533 | * @return true if the marker is visible 534 | */ 535 | public boolean isThumbEnabled() { 536 | return mIsThumbEnabled; 537 | } 538 | 539 | /** 540 | * Sets the marker enabled. 541 | * 542 | * @param enabled the new marker enabled 543 | */ 544 | public void setMarkerEnabled(final boolean enabled) { 545 | mIsMarkerEnabled = enabled; 546 | } 547 | 548 | /** 549 | * Sets the marker progress. 550 | * 551 | * @param progress the new marker progress 552 | */ 553 | public void setMarkerProgress(final float progress) { 554 | mIsMarkerEnabled = true; 555 | mMarkerProgress = progress; 556 | } 557 | 558 | /** 559 | * Sets the progress. 560 | * 561 | * @param progress the new progress 562 | */ 563 | public void setProgress(final float progress) { 564 | if (progress == mProgress) { 565 | return; 566 | } 567 | 568 | if (progress == 1) { 569 | mOverrdraw = false; 570 | mProgress = 1; 571 | } else { 572 | 573 | if (progress >= 1) { 574 | mOverrdraw = true; 575 | } else { 576 | mOverrdraw = false; 577 | } 578 | 579 | mProgress = progress % 1.0f; 580 | } 581 | 582 | if (!mIsInitializing) { 583 | invalidate(); 584 | } 585 | } 586 | 587 | /** 588 | * Sets the progress background color. 589 | * 590 | * @param color the new progress background color 591 | */ 592 | public void setProgressBackgroundColor(final int color) { 593 | mProgressBackgroundColor = color; 594 | updateBackgroundColor(); 595 | } 596 | 597 | private void setMarkerProgressColor(int color) { 598 | mMarkerProgressColor = color; 599 | updateMarkerColor(); 600 | } 601 | 602 | /** 603 | * Sets the progress color. 604 | * 605 | * @param color the new progress color 606 | */ 607 | public void setProgressColor(final int color) { 608 | mProgressColor = color; 609 | 610 | updateProgressColor(); 611 | } 612 | 613 | /** 614 | * shows or hides the thumb of the progress bar 615 | * 616 | * @param enabled true to show the thumb 617 | */ 618 | public void setThumbEnabled(final boolean enabled) { 619 | mIsThumbEnabled = enabled; 620 | } 621 | 622 | /** 623 | * Sets the wheel size. 624 | * 625 | * @param dimension the new wheel size 626 | */ 627 | public void setWheelSize(final int dimension) { 628 | mCircleStrokeWidth = dimension; 629 | 630 | // update the paints 631 | updateBackgroundColor(); 632 | updateMarkerColor(); 633 | updateProgressColor(); 634 | } 635 | 636 | /** 637 | * Compute insets. 638 | *
639 | *
640 | * ______________________ 641 | * |_________dx/2_________| 642 | * |......| /'''''\|......| 643 | * |-dx/2-|| View ||-dx/2-| 644 | * |______| \_____/|______| 645 | * |________ dx/2_________| 646 | *647 | * 648 | * @param dx the dx the horizontal unfilled space 649 | * @param dy the dy the horizontal unfilled space 650 | */ 651 | @SuppressLint("NewApi") 652 | private void computeInsets(final int dx, final int dy) { 653 | int absoluteGravity = mGravity; 654 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { 655 | absoluteGravity = Gravity.getAbsoluteGravity(mGravity, getLayoutDirection()); 656 | } 657 | 658 | switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) { 659 | case Gravity.LEFT: 660 | mHorizontalInset = 0; 661 | break; 662 | case Gravity.RIGHT: 663 | mHorizontalInset = dx; 664 | break; 665 | case Gravity.CENTER_HORIZONTAL: 666 | default: 667 | mHorizontalInset = dx / 2; 668 | break; 669 | } 670 | switch (absoluteGravity & Gravity.VERTICAL_GRAVITY_MASK) { 671 | case Gravity.TOP: 672 | mVerticalInset = 0; 673 | break; 674 | case Gravity.BOTTOM: 675 | mVerticalInset = dy; 676 | break; 677 | case Gravity.CENTER_VERTICAL: 678 | default: 679 | mVerticalInset = dy / 2; 680 | break; 681 | } 682 | } 683 | 684 | /** 685 | * Gets the current rotation. 686 | * 687 | * @return the current rotation 688 | */ 689 | private float getCurrentRotation() { 690 | return 360 * mProgress; 691 | } 692 | 693 | /** 694 | * Gets the marker rotation. 695 | * 696 | * @return the marker rotation 697 | */ 698 | private float getMarkerRotation() { 699 | return 360 * mMarkerProgress; 700 | } 701 | 702 | /** 703 | * updates the paint of the background 704 | */ 705 | private void updateBackgroundColor() { 706 | mBackgroundColorPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 707 | mBackgroundColorPaint.setColor(mProgressBackgroundColor); 708 | mBackgroundColorPaint.setStyle(Paint.Style.STROKE); 709 | mBackgroundColorPaint.setStrokeWidth(mCircleStrokeWidth); 710 | 711 | invalidate(); 712 | } 713 | 714 | /** 715 | * updates the paint of the marker 716 | */ 717 | private void updateMarkerColor() { 718 | mMarkerColorPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 719 | mMarkerColorPaint.setColor(mMarkerProgressColor); 720 | mMarkerColorPaint.setStyle(Paint.Style.FILL); 721 | // mMarkerColorPaint.setStrokeWidth(mCircleStrokeWidth / 2); 722 | 723 | mMarkerTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); 724 | mMarkerTextPaint.setColor(mMarkerProgressColor); 725 | mMarkerTextPaint.setTextSize(mMarkerProgressTextSize); 726 | mMarkerTextPaint.setTextAlign(Paint.Align.CENTER); 727 | invalidate(); 728 | } 729 | 730 | /** 731 | * updates the paint of the progress and the thumb to give them a new visual style 732 | */ 733 | private void updateProgressColor() { 734 | mProgressColorPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 735 | mProgressColorPaint.setColor(mProgressColor); 736 | mProgressColorPaint.setStyle(Paint.Style.STROKE); 737 | mProgressColorPaint.setStrokeWidth(mCircleStrokeWidth); 738 | mProgressColorPaint.setStrokeCap(Paint.Cap.ROUND); 739 | 740 | mThumbColorPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 741 | mThumbColorPaint.setColor(mProgressColor); 742 | mThumbColorPaint.setStyle(Paint.Style.FILL); 743 | mThumbColorPaint.setStrokeWidth(mCircleStrokeWidth); 744 | 745 | 746 | mThumbCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG); 747 | mThumbCirclePaint.setColor(mThumbStrokeColor); 748 | mThumbCirclePaint.setStyle(Paint.Style.STROKE); 749 | mThumbCirclePaint.setStrokeWidth(mCircleStrokeWidth); 750 | 751 | mThumbTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); 752 | mThumbTextPaint.setColor(mProgressColor); 753 | mThumbTextPaint.setTextSize(mThumbStrokeTextSize); 754 | mThumbTextPaint.setTextAlign(Paint.Align.CENTER); 755 | 756 | // mThumbBitmapPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 757 | // mThumbBitmapPaint.setFilterBitmap(true); 758 | // mThumbBitmapPaint.setDither(true); 759 | 760 | 761 | invalidate(); 762 | } 763 | 764 | /** 765 | * Determines the width of this view 766 | * 767 | * @param measureSpec A measureSpec packed into an int 768 | * @return The width of the view, honoring constraints from measureSpec 769 | */ 770 | private int measureWidth(int measureSpec) { 771 | int result = 0; 772 | int specMode = MeasureSpec.getMode(measureSpec); 773 | int specSize = MeasureSpec.getSize(measureSpec); 774 | 775 | if (specMode == MeasureSpec.EXACTLY) { 776 | // We were told how big to be 777 | result = specSize; 778 | } else { 779 | // Measure the text 780 | result = getPaddingLeft() 781 | + getPaddingRight(); 782 | if (specMode == MeasureSpec.AT_MOST) { 783 | // Respect AT_MOST value if that was what is called for by measureSpec 784 | result = Math.min(result, specSize); 785 | } 786 | } 787 | 788 | return result; 789 | } 790 | 791 | /** 792 | * Determines the height of this view 793 | * 794 | * @param measureSpec A measureSpec packed into an int 795 | * @return The height of the view, honoring constraints from measureSpec 796 | */ 797 | private int measureHeight(int measureSpec) { 798 | int result = 0; 799 | int specMode = MeasureSpec.getMode(measureSpec); 800 | int specSize = MeasureSpec.getSize(measureSpec); 801 | 802 | if (specMode == MeasureSpec.EXACTLY) { 803 | // We were told how big to be 804 | result = specSize; 805 | } else { 806 | // Measure the text (beware: ascent is a negative number) 807 | result = getPaddingTop() 808 | + getPaddingBottom(); 809 | if (specMode == MeasureSpec.AT_MOST) { 810 | // Respect AT_MOST value if that was what is called for by measureSpec 811 | result = Math.min(result, specSize); 812 | } 813 | } 814 | 815 | return result; 816 | } 817 | 818 | } 819 | --------------------------------------------------------------------------------