自定義progress之三種風格的圖片載入進度顯示樣式
阿新 • • 發佈:2019-10-08
public class CircleProgressView extends ProgressBar { private int mReachBarSize = DisplayUtil.dip2px(getContext(), 2); // 未完成進度條大小 private int mNormalBarSize = DisplayUtil.dip2px(getContext(), 2); // 未完成進度條大小 private int mReachBarColor = Color.parseColor("#108ee9"); // 已完成進度顏色 private int mNormalBarColor = Color.parseColor("#FFD3D6DA"); // 未完成進度顏色 private int mTextSize = DisplayUtil.sp2px(getContext(), 14); // 進度值字型大小 private int mTextColor = Color.parseColor("#108ee9"); // 進度的值字型顏色 private float mTextSkewX; // 進度值字型傾斜角度 private String mTextSuffix = "%"; // 進度值字首 private String mTextPrefix = ""; // 進度值字尾 private boolean mTextVisible = true; // 是否顯示進度值 private boolean mReachCapRound; // 畫筆是否使用圓角邊界,normalStyle下生效 private int mRadius = DisplayUtil.dip2px(getContext(), 20); // 半徑 private int mStartArc; // 起始角度 private int mInnerBackgroundColor; // 內部背景填充顏色 private int mProgressStyle = ProgressStyle.NORMAL; // 進度風格 private int mInnerPadding = DisplayUtil.dip2px(getContext(), 1); // 內部圓與外部圓間距 private int mOuterColor; // 外部圓環顏色 private boolean needDrawInnerBackground; // 是否需要繪製內部背景 private RectF rectF; // 外部圓環繪製區域 private RectF rectInner; // 內部圓環繪製區域 private int mOuterSize = DisplayUtil.dip2px(getContext(), 1); // 外層圓環寬度 private Paint mTextPaint; // 繪製進度值字型畫筆 private Paint mNormalPaint; // 繪製未完成進度畫筆 private Paint mReachPaint; // 繪製已完成進度畫筆 private Paint mInnerBackgroundPaint; // 內部背景畫筆 private Paint mOutPaint; // 外部圓環畫筆 private int mRealWidth; private int mRealHeight; @IntDef({ProgressStyle.NORMAL, ProgressStyle.FILL_IN, ProgressStyle.FILL_IN_ARC}) @Retention(RetentionPolicy.SOURCE) public @interface ProgressStyle { int NORMAL = 0; int FILL_IN = 1; int FILL_IN_ARC = 2; } public CircleProgressView(Context context) { this(context, null); } public CircleProgressView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public CircleProgressView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); obtainAttributes(attrs); initPaint(); } private void initPaint() { mTextPaint = new Paint(); mTextPaint.setColor(mTextColor); mTextPaint.setStyle(Paint.Style.FILL); mTextPaint.setTextSize(mTextSize); mTextPaint.setTextSkewX(mTextSkewX); mTextPaint.setAntiAlias(true); mNormalPaint = new Paint(); mNormalPaint.setColor(mNormalBarColor); mNormalPaint.setStyle(mProgressStyle == ProgressStyle.FILL_IN_ARC ? Paint.Style.FILL : Paint.Style.STROKE); mNormalPaint.setAntiAlias(true); mNormalPaint.setStrokeWidth(mNormalBarSize); mReachPaint = new Paint(); mReachPaint.setColor(mReachBarColor); mReachPaint.setStyle(mProgressStyle == ProgressStyle.FILL_IN_ARC ? Paint.Style.FILL : Paint.Style.STROKE); mReachPaint.setAntiAlias(true); mReachPaint.setStrokeCap(mReachCapRound ? Paint.Cap.ROUND : Paint.Cap.BUTT); mReachPaint.setStrokeWidth(mReachBarSize); if (needDrawInnerBackground) { mInnerBackgroundPaint = new Paint(); mInnerBackgroundPaint.setStyle(Paint.Style.FILL); mInnerBackgroundPaint.setAntiAlias(true); mInnerBackgroundPaint.setColor(mInnerBackgroundColor); } if (mProgressStyle == ProgressStyle.FILL_IN_ARC) { mOutPaint = new Paint(); mOutPaint.setStyle(Paint.Style.STROKE); mOutPaint.setColor(mOuterColor); mOutPaint.setStrokeWidth(mOuterSize); mOutPaint.setAntiAlias(true); } } private void obtainAttributes(AttributeSet attrs) { TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.CircleProgressView); mProgressStyle = ta.getInt(R.styleable.CircleProgressView_cpv_progressStyle, ProgressStyle.NORMAL); // 獲取三種風格通用的屬性 mNormalBarSize = (int) ta.getDimension(R.styleable.CircleProgressView_cpv_progressNormalSize, mNormalBarSize); mNormalBarColor = ta.getColor(R.styleable.CircleProgressView_cpv_progressNormalColor, mNormalBarColor); mReachBarSize = (int) ta.getDimension(R.styleable.CircleProgressView_cpv_progressReachSize, mReachBarSize); mReachBarColor = ta.getColor(R.styleable.CircleProgressView_cpv_progressReachColor, mReachBarColor); mTextSize = (int) ta.getDimension(R.styleable.CircleProgressView_cpv_progressTextSize, mTextSize); mTextColor = ta.getColor(R.styleable.CircleProgressView_cpv_progressTextColor, mTextColor); mTextSkewX = ta.getDimension(R.styleable.CircleProgressView_cpv_progressTextSkewX, 0); if (ta.hasValue(R.styleable.CircleProgressView_cpv_progressTextSuffix)) { mTextSuffix = ta.getString(R.styleable.CircleProgressView_cpv_progressTextSuffix); } if (ta.hasValue(R.styleable.CircleProgressView_cpv_progressTextPrefix)) { mTextPrefix = ta.getString(R.styleable.CircleProgressView_cpv_progressTextPrefix); } mTextVisible = ta.getBoolean(R.styleable.CircleProgressView_cpv_progressTextVisible, mTextVisible); mRadius = (int) ta.getDimension(R.styleable.CircleProgressView_cpv_radius, mRadius); rectF = new RectF(-mRadius, -mRadius, mRadius, mRadius); switch (mProgressStyle) { case ProgressStyle.FILL_IN: mReachBarSize = 0; mNormalBarSize = 0; mOuterSize = 0; break; case ProgressStyle.FILL_IN_ARC: mStartArc = ta.getInt(R.styleable.CircleProgressView_cpv_progressStartArc, 0) + 270; mInnerPadding = (int) ta.getDimension(R.styleable.CircleProgressView_cpv_innerPadding, mInnerPadding); mOuterColor = ta.getColor(R.styleable.CircleProgressView_cpv_outerColor, mReachBarColor); mOuterSize = (int) ta.getDimension(R.styleable.CircleProgressView_cpv_outerSize, mOuterSize); mReachBarSize = 0;// 將畫筆大小重置為0 mNormalBarSize = 0; if (!ta.hasValue(R.styleable.CircleProgressView_cpv_progressNormalColor)) { mNormalBarColor = Color.TRANSPARENT; } int mInnerRadius = mRadius - mOuterSize / 2 - mInnerPadding; rectInner = new RectF(-mInnerRadius, -mInnerRadius, mInnerRadius, mInnerRadius); break; case ProgressStyle.NORMAL: mReachCapRound = ta.getBoolean(R.styleable.CircleProgressView_cpv_reachCapRound, true); mStartArc = ta.getInt(R.styleable.CircleProgressView_cpv_progressStartArc, 0) + 270; if (ta.hasValue(R.styleable.CircleProgressView_cpv_innerBackgroundColor)) { mInnerBackgroundColor = ta.getColor(R.styleable.CircleProgressView_cpv_innerBackgroundColor, Color.argb(0, 0, 0, 0)); needDrawInnerBackground = true; } break; } ta.recycle(); } @Override protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int maxBarPaintWidth = Math.max(mReachBarSize, mNormalBarSize); int maxPaintWidth = Math.max(maxBarPaintWidth, mOuterSize); int height = 0; int width = 0; switch (mProgressStyle) { case ProgressStyle.FILL_IN: height = getPaddingTop() + getPaddingBottom() // 邊距 + Math.abs(mRadius * 2); // 直徑 width = getPaddingLeft() + getPaddingRight() // 邊距 + Math.abs(mRadius * 2); // 直徑 break; case ProgressStyle.FILL_IN_ARC: height = getPaddingTop() + getPaddingBottom() // 邊距 + Math.abs(mRadius * 2) // 直徑 + maxPaintWidth;// 邊框 width = getPaddingLeft() + getPaddingRight() // 邊距 + Math.abs(mRadius * 2) // 直徑 + maxPaintWidth;// 邊框 break; case ProgressStyle.NORMAL: height = getPaddingTop() + getPaddingBottom() // 邊距 + Math.abs(mRadius * 2) // 直徑 + maxBarPaintWidth;// 邊框 width = getPaddingLeft() + getPaddingRight() // 邊距 + Math.abs(mRadius * 2) // 直徑 + maxBarPaintWidth;// 邊框 break; } mRealWidth = resolveSize(width, widthMeasureSpec); mRealHeight = resolveSize(height, heightMeasureSpec); setMeasuredDimension(mRealWidth, mRealHeight); } @Override protected synchronized void onDraw(Canvas canvas) { switch (mProgressStyle) { case ProgressStyle.NORMAL: drawNormalCircle(canvas); break; case ProgressStyle.FILL_IN: drawFillInCircle(canvas); break; case ProgressStyle.FILL_IN_ARC: drawFillInArcCircle(canvas); break; } } /** * 繪製PROGRESS_STYLE_FILL_IN_ARC圓形 */ private void drawFillInArcCircle(Canvas canvas) { canvas.save(); canvas.translate(mRealWidth / 2, mRealHeight / 2); // 繪製外層圓環 canvas.drawArc(rectF, 0, 360, false, mOutPaint); // 繪製內層進度實心圓弧 // 內層圓弧半徑 float reachArc = getProgress() * 1.0f / getMax() * 360; canvas.drawArc(rectInner, mStartArc, reachArc, true, mReachPaint); // 繪製未到達進度 if (reachArc != 360) { canvas.drawArc(rectInner, reachArc + mStartArc, 360 - reachArc, true, mNormalPaint); } canvas.restore(); } /** * 繪製PROGRESS_STYLE_FILL_IN圓形 */ private void drawFillInCircle(Canvas canvas) { canvas.save(); canvas.translate(mRealWidth / 2, mRealHeight / 2); float progressY = getProgress() * 1.0f / getMax() * (mRadius * 2); float angle = (float) (Math.acos((mRadius - progressY) / mRadius) * 180 / Math.PI); float startAngle = 90 + angle; float sweepAngle = 360 - angle * 2; // 繪製未到達區域 rectF = new RectF(-mRadius, -mRadius, mRadius, mRadius); mNormalPaint.setStyle(Paint.Style.FILL); canvas.drawArc(rectF, startAngle, sweepAngle, false, mNormalPaint); // 翻轉180度繪製已到達區域 canvas.rotate(180); mReachPaint.setStyle(Paint.Style.FILL); canvas.drawArc(rectF, 270 - angle, angle * 2, false, mReachPaint); // 文字顯示在最上層最後繪製 canvas.rotate(180); // 繪製文字 if (mTextVisible) { String text = mTextPrefix + getProgress() + mTextSuffix; float textWidth = mTextPaint.measureText(text); float textHeight = (mTextPaint.descent() + mTextPaint.ascent()); canvas.drawText(text, -textWidth / 2, -textHeight / 2, mTextPaint); } } /** * 繪製PROGRESS_STYLE_NORMAL圓形 */ private void drawNormalCircle(Canvas canvas) { canvas.save(); canvas.translate(mRealWidth / 2, mRealHeight / 2); // 繪製內部圓形背景色 if (needDrawInnerBackground) { canvas.drawCircle(0, 0, mRadius - Math.min(mReachBarSize, mNormalBarSize) / 2, mInnerBackgroundPaint); } // 繪製文字 if (mTextVisible) { String text = mTextPrefix + getProgress() + mTextSuffix; float textWidth = mTextPaint.measureText(text); float textHeight = (mTextPaint.descent() + mTextPaint.ascent()); canvas.drawText(text, -textWidth / 2, -textHeight / 2, mTextPaint); } // 計算進度值 float reachArc = getProgress() * 1.0f / getMax() * 360; // 繪製未到達進度 if (reachArc != 360) { canvas.drawArc(rectF, reachArc + mStartArc, 360 - reachArc, false, mNormalPaint); } // 繪製已到達進度 canvas.drawArc(rectF, mStartArc, reachArc, false, mReachPaint); canvas.restore(); } /** * 動畫進度(0-當前進度) * * @param duration 動畫時長 */ public void runProgressAnim(long duration) { setProgressInTime(0, duration); } /** * @param progress 進度值 * @param duration 動畫播放時間 */ public void setProgressInTime(final int progress, final long duration) { setProgressInTime(progress, getProgress(), duration); } /** * @param startProgress 起始進度 * @param progress 進度值 * @param duration 動畫播放時間 */ public void setProgressInTime(int startProgress, final int progress, final long duration) { ValueAnimator valueAnimator = ValueAnimator.ofInt(startProgress, progress); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animator) { //獲得當前動畫的進度值,整型,1-100之間 int currentValue = (Integer) animator.getAnimatedValue(); setProgress(currentValue); } }); AccelerateDecelerateInterpolator interpolator = new AccelerateDecelerateInterpolator(); valueAnimator.setInterpolator(interpolator); valueAnimator.setDuration(duration); valueAnimator.start(); } public int getReachBarSize() { return mReachBarSize; } public void setReachBarSize(int reachBarSize) { mReachBarSize = DisplayUtil.dip2px(getContext(), reachBarSize); invalidate(); } public int getNormalBarSize() { return mNormalBarSize; } public void setNormalBarSize(int normalBarSize) { mNormalBarSize = DisplayUtil.dip2px(getContext(), normalBarSize); invalidate(); } public int getReachBarColor() { return mReachBarColor; } public void setReachBarColor(int reachBarColor) { mReachBarColor = reachBarColor; invalidate(); } public int getNormalBarColor() { return mNormalBarColor; } public void setNormalBarColor(int normalBarColor) { mNormalBarColor = normalBarColor; invalidate(); } public int getTextSize() { return mTextSize; } public void setTextSize(int textSize) { mTextSize = DisplayUtil.sp2px(getContext(), textSize); invalidate(); } public int getTextColor() { return mTextColor; } public void setTextColor(int textColor) { mTextColor = textColor; invalidate(); } public float getTextSkewX() { return mTextSkewX; } public void setTextSkewX(float textSkewX) { mTextSkewX = textSkewX; invalidate(); } public String getTextSuffix() { return mTextSuffix; } public void setTextSuffix(String textSuffix) { mTextSuffix = textSuffix; invalidate(); } public String getTextPrefix() { return mTextPrefix; } public void setTextPrefix(String textPrefix) { mTextPrefix = textPrefix; invalidate(); } public boolean isTextVisible() { return mTextVisible; } public void setTextVisible(boolean textVisible) { mTextVisible = textVisible; invalidate(); } public boolean isReachCapRound() { return mReachCapRound; } public void setReachCapRound(boolean reachCapRound) { mReachCapRound = reachCapRound; invalidate(); } public int getRadius() { return mRadius; } public void setRadius(int radius) { mRadius = DisplayUtil.dip2px(getContext(), radius); invalidate(); } public int getStartArc() { return mStartArc; } public void setStartArc(int startArc) { mStartArc = startArc; invalidate(); } public int getInnerBackgroundColor() { return mInnerBackgroundColor; } public void setInnerBackgroundColor(int innerBackgroundColor) { mInnerBackgroundColor = innerBackgroundColor; invalidate(); } public int getProgressStyle() { return mProgressStyle; } public void setProgressStyle(int progressStyle) { mProgressStyle = progressStyle; invalidate(); } public int getInnerPadding() { return mInnerPadding; } public void setInnerPadding(int innerPadding) { mInnerPadding = DisplayUtil.dip2px(getContext(), innerPadding); int mInnerRadius = mRadius - mOuterSize / 2 - mInnerPadding; rectInner = new RectF(-mInnerRadius, -mInnerRadius, mInnerRadius, mInnerRadius); invalidate(); } public int getOuterColor() { return mOuterColor; } public void setOuterColor(int outerColor) { mOuterColor = outerColor; invalidate(); } public int getOuterSize() { return mOuterSize; } public void setOuterSize(int outerSize) { mOuterSize = DisplayUtil.dip2px(getContext(), outerSize); invalidate(); } private static final String STATE = "state"; private static final String PROGRESS_STYLE = "progressStyle"; private static final String TEXT_COLOR = "textColor"; private static final String TEXT_SIZE = "textSize"; private static final String TEXT_SKEW_X = "textSkewX"; private static final String TEXT_VISIBLE = "textVisible"; private static final String TEXT_SUFFIX = "textSuffix"; private static final String TEXT_PREFIX = "textPrefix"; private static final String REACH_BAR_COLOR = "reachBarColor"; private static final String REACH_BAR_SIZE = "reachBarSize"; private static final String NORMAL_BAR_COLOR = "normalBarColor"; private static final String NORMAL_BAR_SIZE = "normalBarSize"; private static final String IS_REACH_CAP_ROUND = "isReachCapRound"; private static final String RADIUS = "radius"; private static final String START_ARC = "startArc"; private static final String INNER_BG_COLOR = "innerBgColor"; private static final String INNER_PADDING = "innerPadding"; private static final String OUTER_COLOR = "outerColor"; private static final String OUTER_SIZE = "outerSize"; @Override public Parcelable onSaveInstanceState() { final Bundle bundle = new Bundle(); bundle.putParcelable(STATE, super.onSaveInstanceState()); // 儲存當前樣式 bundle.putInt(PROGRESS_STYLE, getProgressStyle()); bundle.putInt(RADIUS, getRadius()); bundle.putBoolean(IS_REACH_CAP_ROUND, isReachCapRound()); bundle.putInt(START_ARC, getStartArc()); bundle.putInt(INNER_BG_COLOR, getInnerBackgroundColor()); bundle.putInt(INNER_PADDING, getInnerPadding()); bundle.putInt(OUTER_COLOR, getOuterColor()); bundle.putInt(OUTER_SIZE, getOuterSize()); // 儲存text資訊 bundle.putInt(TEXT_COLOR, getTextColor()); bundle.putInt(TEXT_SIZE, getTextSize()); bundle.putFloat(TEXT_SKEW_X, getTextSkewX()); bundle.putBoolean(TEXT_VISIBLE, isTextVisible()); bundle.putString(TEXT_SUFFIX, getTextSuffix()); bundle.putString(TEXT_PREFIX, getTextPrefix()); // 儲存已到達進度資訊 bundle.putInt(REACH_BAR_COLOR, getReachBarColor()); bundle.putInt(REACH_BAR_SIZE, getReachBarSize()); // 儲存未到達進度資訊 bundle.putInt(NORMAL_BAR_COLOR, getNormalBarColor()); bundle.putInt(NORMAL_BAR_SIZE, getNormalBarSize()); return bundle; } @Override public void onRestoreInstanceState(Parcelable state) { if (state instanceof Bundle) { final Bundle bundle = (Bundle) state; mProgressStyle = bundle.getInt(PROGRESS_STYLE); mRadius = bundle.getInt(RADIUS); mReachCapRound = bundle.getBoolean(IS_REACH_CAP_ROUND); mStartArc = bundle.getInt(START_ARC); mInnerBackgroundColor = bundle.getInt(INNER_BG_COLOR); mInnerPadding = bundle.getInt(INNER_PADDING); mOuterColor = bundle.getInt(OUTER_COLOR); mOuterSize = bundle.getInt(OUTER_SIZE); mTextColor = bundle.getInt(TEXT_COLOR); mTextSize = bundle.getInt(TEXT_SIZE); mTextSkewX = bundle.getFloat(TEXT_SKEW_X); mTextVisible = bundle.getBoolean(TEXT_VISIBLE); mTextSuffix = bundle.getString(TEXT_SUFFIX); mTextPrefix = bundle.getString(TEXT_PREFIX); mReachBarColor = bundle.getInt(REACH_BAR_COLOR); mReachBarSize = bundle.getInt(REACH_BAR_SIZE); mNormalBarColor = bundle.getInt(NORMAL_BAR_COLOR); mNormalBarSize = bundle.getInt(NORMAL_BAR_SIZE); initPaint(); super.onRestoreInstanceState(bundle.getParcelable(STATE)); return; } super.onRestoreInstanceState(state); } @Override public void invalidate() { initPaint(); super.invalidate(); } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
- 499
- 500
- 501
- 502
- 503
- 504
- 505
- 506
- 507
- 508
- 509
- 510
- 511
- 512
- 513
- 514
- 515
- 516
- 517
- 518
- 519
- 520
- 521
- 522
- 523
- 524
- 525
- 526
- 527
- 528
- 529
- 530
- 531
- 532
- 533
- 534
- 535
- 536
- 537
- 538
- 539
- 540
- 541
- 542
- 543
- 544
- 545
- 546
- 547
- 548
- 549
- 550
- 551
- 552
- 553
- 554
- 555
- 556
- 557
- 558
- 559
- 560
- 561
- 562
- 563
- 564
- 565
- 566
- 567
- 568
- 569
工具類DisplayUtil:
public class DisplayUtil {
private static WindowManager windowManager;
private static WindowManager getWindowManager(Context context) {
if (windowManager == null) {
windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
}
return windowManager;
}
// 根據手機的解析度將dp的單位轉成px(畫素)
public static int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
// 根據手機的解析度將px(畫素)的單位轉成dp
public static int px2dip(Context context, float pxValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (pxValue / scale + 0.5f);
}
// 將px值轉換為sp值
public static int px2sp(Context context, float pxValue) {
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
return (int) (pxValue / fontScale + 0.5f);
}
// 將sp值轉換為px值
public static int sp2px(Context context, float spValue) {
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
return (int) (spValue * fontScale + 0.5f);
}
// 螢幕寬度(畫素)
public static int getScreenWidth(Context context) {
DisplayMetrics metric = new DisplayMetrics();
getWindowManager(context).getDefaultDisplay().getMetrics(metric);
return metric.widthPixels;
}
// 螢幕高度(畫素)
public static int getScreenHeight(Context context) {
DisplayMetrics metric = new DisplayMetrics();
getWindowManager(context).getDefaultDisplay().getMetrics(metric);
return metric.heightPixels;
}
public static float getScreenDensity(Context context) {
try {
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager(context).getDefaultDisplay().getMetrics(displayMetrics);
return displayMetrics.density;
} catch (Throwable e) {
e.printStackTrace();
return 1.0f;
}
}
public static int getDensityDpi(Context context) {
try {
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager(context).getDefaultDisplay().getMetrics(displayMetrics);
return displayMetrics.densityDpi;
} catch (Throwable e) {
e.printStackTrace();
return 320;
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
最後還有Style檔案中:
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<declare-styleable name="CircleProgressView">
<attr name="cpv_progressNormalColor" format="color" /> <!--非進度區域的顏色-->
<attr name="cpv_progressReachColor" format="color" /> <!--進度區域的顏色-->
<attr name="cpv_progressTextColor" format="color" /> <!--進度條文字的顏色-->
<attr name="cpv_progressTextSize" format="dimension" /> <!--進度條文字的大小-->
<attr name="cpv_progressTextOffset" format="dimension" /> <!--進度條文字的偏移-->
<attr name="cpv_progressNormalSize" format="dimension" /> <!--正常尺寸-->
<attr name="cpv_progressReachSize" format="dimension" /> <!--進度的尺寸-->
<attr name="cpv_radius" format="dimension" /> <!--半徑,控制顯示大小-->
<attr name="cpv_progressTextVisible" format="boolean" /> <!--進度條文字是否顯示-->
<attr name="cpv_progressStartArc" format="integer" />
<attr name="cpv_progressTextSkewX" format="dimension" />
<attr name="cpv_progressTextPrefix" format="string" />
<attr name="cpv_progressTextSuffix" format="string" />
<attr name="cpv_innerBackgroundColor" format="color" /> <!--內背景顏色-->
<attr name="cpv_progressStyle" format="enum"> <!-- 進度條樣式3選1 -->
<enum name="Normal" value="0" />
<enum name="FillInner" value="1" />
<enum name="FillInnerArc" value="2" />
</attr>
<attr name="cpv_innerProgressColor" format="color" />
<attr name="cpv_innerPadding" format="dimension" />
<attr name="cpv_outerColor" format="color" />
<attr name="cpv_outerSize" format="dimension" />
<attr name="cpv_reachCapRound" format="boolean" />
</declare-styleable>
</resources>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
如何使用
<com.gpf.myapp.CircleProgressView
android:id="@+id/progressView"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerInParent="true"
android:progress="50"
app:cpv_innerPadding="2dp"
app:cpv_outerColor="@color/transparent90_white"
app:cpv_outerSize="1dp"
app:cpv_progressNormalColor="@color/transparent"
app:cpv_progressReachColor="@color/transparent90_white"
app:cpv_progressStyle="FillInnerArc"/>
<com.gpf.myapp.CircleProgressView
android:id="@+id/progressView2"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerInParent="true"
android:layout_margin="10dp"
android:progress="50"
app:cpv_progressNormalColor="@color/transparent10"
app:cpv_progressReachColor="@color/transparent90_white"
app:cpv_progressStyle="FillInner"
app:cpv_progressTextColor="@color/red"
app:cpv_progressTextSize="13sp"
app:cpv_progressTextVisible="true"/>
<com.gpf.myapp.CircleProgressView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerInParent="true"
android:progress="50"
app:cpv_innerPadding="2dp"
app:cpv_outerColor="@color/transparent90_white"
app:cpv_outerSize="1dp"
app:cpv_progressNormalColor="@color/transparent"
app:cpv_progressReachColor="@color/transparent90_white"
app:cpv_progressStyle="Normal"/>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
提供幾個顏色資源:
<color name="transparent">#00000000</color>
<color name="transparent90_white">#E5ffffff</color>
<color name="transparent10">#1A000000</color>
<color name="placeholder">#33000000</color>
<color name="placeholder_yellow">#33fbc02d</color>
<color name="placeholder_orange">#33f57c00</color>
<color name="white">#FFFFFF</color> <!-- 白色 -->
<color name="yellow">#fbc02d</color> <!-- 黃色 -->
<color name="gold">#FFD700</color> <!-- 金色 -->
<color name="orange">#f57c00</color> <!-- 橙色 -->
<color name="red">#d01716</color> <!-- 紅色 -->
<color name="gray">#808080</color> <!-- 灰色 -->
<color name="green">#0a7e07</color> <!-- 綠色 -->
<color name="blue">#455ede</color> <!-- 藍色 -->
<color name="black">#000000</color> <!--