網站首頁 編程語言 正文
Android中實現進度條有很多種方式,自定義進度條一般是繼承progressBar或繼承view來實現,本篇中講解的是第二種方式。
先上效果圖:
實現圓形進度條總體來說并不難,還是跟往常一樣繼承view,初始化畫筆,按下面的步驟一步步來就好了。對初學者來說動畫效果可能比較陌生,我們可以使用屬性動畫中的valueAnimator來實現動畫效果。
實現步驟:
1、畫出一個灰色的圓環作為背景。
2、畫出上層的圓環覆蓋下方的圓環。
3、加入動畫效果
值得注意的是怎么設置圓環和文字的位置。
畫出矩形只需要傳入矩形對角線的坐標即可,如果不加以處理的話畫出來的圓環的邊緣是不完整的,剛開始接觸自定義view的同學們一定要先好好看看Android坐標系相關內容,不然很難理解位置參數為什么這樣設置。
完整代碼:
package com.example.floatingwindow.widget; import android.animation.ValueAnimator; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.RectF; import android.util.AttributeSet; import android.util.TypedValue; import android.view.View; import android.view.animation.DecelerateInterpolator; import androidx.annotation.Nullable; import com.example.floatingwindow.R; public class ProgressBarView extends View { private Paint mPaintBack; private Paint mPaint; private Paint mPaintText; private float process; private int strokeWidth = 15; private int textSize = 20; private long duration = 3000; private float startDegree = 0; private float endDegree = 360; private String text = "完成"; private String defaultText = "0%"; public ProgressBarView(Context context) { super(context); init(); } public ProgressBarView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(); } public ProgressBarView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { mPaintBack = new Paint(); mPaintBack.setColor(getResources().getColor(R.color.gray)); mPaintBack.setStyle(Paint.Style.STROKE); mPaintBack.setAntiAlias(true); mPaintBack.setStrokeCap(Paint.Cap.ROUND); mPaintBack.setStrokeWidth(strokeWidth); mPaint = new Paint(); mPaint.setColor(getResources().getColor(R.color.purple_200)); mPaint.setStyle(Paint.Style.STROKE); mPaint.setAntiAlias(true); mPaint.setStrokeCap(Paint.Cap.ROUND); mPaint.setStrokeWidth(strokeWidth); mPaintText = new Paint(); mPaintText.setAntiAlias(true); mPaintText.setStyle(Paint.Style.STROKE); mPaintText.setColor(Color.BLACK); mPaintBack.setStrokeCap(Paint.Cap.ROUND); mPaintText.setTextSize(sp2px(textSize)); } public void setStrokeWidth(int width) { strokeWidth = width; } public void setTextSize(int textSize) { this.textSize = textSize; } public void setDuration(long duration) { this.duration = duration; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //創建圓環矩形 RectF rectF = new RectF(strokeWidth, strokeWidth, getWidth() - strokeWidth, getHeight() - strokeWidth); //畫出灰色進度條作為背景 canvas.drawArc(rectF, 0, 360, false, mPaintBack); //畫進度條 canvas.drawArc(rectF, 0, process, false, mPaint); //計算進度 int percent = (int) (process / 360 * 100); //設置文字在canvas中的位置 Paint.FontMetrics fm = mPaintText.getFontMetrics(); int mTxtWidth = (int) mPaintText.measureText(text, 0, defaultText.length()); int mTxtHeight = (int) Math.ceil(fm.descent - fm.ascent); int x = getWidth() / 2 - mTxtWidth / 2; int y = getHeight() / 2 + mTxtHeight / 4; if (percent < 100) { canvas.drawText(percent + "%", x, y, mPaintText); } else { canvas.drawText(text, x, y, mPaintText); } } /** * 設置動畫效果 */ public void start() { ValueAnimator valueAnimator = ValueAnimator.ofFloat(startDegree, endDegree); valueAnimator.setDuration(duration); valueAnimator.setInterpolator(new DecelerateInterpolator()); valueAnimator.addUpdateListener(animation -> { process = (float) animation.getAnimatedValue(); invalidate(); }); valueAnimator.start(); } private int sp2px(int sp) { return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, getResources().getDisplayMetrics()); } }
最后就是動畫效果了,使用valueanimator,傳入開始和結束的進度以及執行時間。然后每次進度發生變化時做UI刷新。
xml布局:
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <com.example.floatingwindow.widget.ProgressBarView android:id="@+id/progressBar" android:layout_width="150dp" android:layout_height="150dp" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent"> </com.example.floatingwindow.widget.ProgressBarView> </androidx.constraintlayout.widget.ConstraintLayout>
MainActivity:
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) progressBar.start() progressBar.setOnClickListener { progressBar.start()} }
原文鏈接:https://blog.csdn.net/daydayup05/article/details/122150161
相關推薦
- 2022-02-17 藍屏終止代碼:WHEA_UNCORRECTABLE_ERROR
- 2023-12-10 Failed to process, please exclude the tableName or
- 2021-07-18 vscode sftp no such file 解決辦法
- 2022-12-28 詳解Go語言strconv與其他基本數據類型轉換函數的使用_Golang
- 2022-04-18 Android?app本地切換logo和名稱_Android
- 2022-12-01 SQL?Server數據庫分離和附加數據庫的操作步驟_MsSql
- 2022-07-26 ubuntu18.04+cuda10.2+tensorrt8.4.1.5配置安裝
- 2022-05-24 淺談C#中Action和Func回調的常用方式_C#教程
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支