Android自定義view實現(xiàn)圓形進(jìn)度條效果
Android中實現(xiàn)進(jìn)度條有很多種方式,自定義進(jìn)度條一般是繼承progressBar或繼承view來實現(xiàn),本篇中講解的是第二種方式。
先上效果圖:
實現(xiàn)圓形進(jìn)度條總體來說并不難,還是跟往常一樣繼承view,初始化畫筆,按下面的步驟一步步來就好了。對初學(xué)者來說動畫效果可能比較陌生,我們可以使用屬性動畫中的valueAnimator來實現(xiàn)動畫效果。
實現(xiàn)步驟:
1、畫出一個灰色的圓環(huán)作為背景。
2、畫出上層的圓環(huán)覆蓋下方的圓環(huán)。
3、加入動畫效果
值得注意的是怎么設(shè)置圓環(huán)和文字的位置。
畫出矩形只需要傳入矩形對角線的坐標(biāo)即可,如果不加以處理的話畫出來的圓環(huán)的邊緣是不完整的,剛開始接觸自定義view的同學(xué)們一定要先好好看看Android坐標(biāo)系相關(guān)內(nèi)容,不然很難理解位置參數(shù)為什么這樣設(shè)置。
完整代碼:
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); ? ? ? ? //創(chuàng)建圓環(huán)矩形 ? ? ? ? RectF rectF = new RectF(strokeWidth, strokeWidth, getWidth() - strokeWidth, getHeight() - strokeWidth); ? ? ? ? //畫出灰色進(jìn)度條作為背景 ? ? ? ? canvas.drawArc(rectF, 0, 360, false, mPaintBack); ? ? ? ? //畫進(jìn)度條 ? ? ? ? canvas.drawArc(rectF, 0, process, false, mPaint); ? ? ? ? //計算進(jìn)度 ? ? ? ? int percent = (int) (process / 360 * 100); ? ? ? ? //設(shè)置文字在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); ? ? ? ? } ? ? } ? ? ? /** ? ? ?* 設(shè)置動畫效果 ? ? ?*/ ? ? 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,傳入開始和結(jié)束的進(jìn)度以及執(zhí)行時間。然后每次進(jìn)度發(fā)生變化時做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()} ? ? }
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- android自定義進(jìn)度條漸變色View的實例代碼
- Android中實現(xiàn)Webview頂部帶進(jìn)度條的方法
- android ListView和ProgressBar(進(jìn)度條控件)的使用方法
- Android自定義View實現(xiàn)漸變色進(jìn)度條
- Android中WebView加載網(wǎng)頁設(shè)置進(jìn)度條
- Android自定義View實現(xiàn)帶數(shù)字的進(jìn)度條實例代碼
- Android自定義View實現(xiàn)水平帶數(shù)字百分比進(jìn)度條
- Android Webview添加網(wǎng)頁加載進(jìn)度條實例詳解
- Android 自定義view和屬性動畫實現(xiàn)充電進(jìn)度條效果
- Android自定義View仿華為圓形加載進(jìn)度條
相關(guān)文章
總結(jié)Android中MD風(fēng)格相關(guān)控件
自Android5.0發(fā)布以來,谷歌推出全新的Material Desigen設(shè)計風(fēng)格,時過一年多了,在國內(nèi)也看到很多應(yīng)用在慢慢適應(yīng)MD設(shè)計風(fēng)格。今天小編給大家總結(jié)下Android中MD風(fēng)格相關(guān)控件的知識,有需要的可以參考學(xué)習(xí)。2016-08-08Android中WebView實現(xiàn)點擊超鏈接啟動QQ的方法
這篇文章主要給大家介紹了在Android中WebView如何實現(xiàn)點擊超鏈接啟動QQ的方法,文中給出了詳細(xì)的示例代碼,相信對大家的學(xué)習(xí)或者工作具有一定的參考價值,需要的朋友們下面來一起看看吧。2017-04-04Android中 TeaScreenPopupWindow多類型篩選彈框功能的實例代碼
這篇文章主要介紹了Android TeaScreenPopupWindow多類型篩選彈框功能,本文通過實例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價值 ,需要的朋友可以參考下2019-06-06Android基于OpenGL的GLSurfaceView創(chuàng)建一個Activity實現(xiàn)方法
這篇文章主要介紹了Android基于OpenGL的GLSurfaceView創(chuàng)建一個Activity實現(xiàn)方法,結(jié)合實例形式分析了Android中OpenGL圖形操作類GLSurfaceView的功能、用法及相關(guān)使用技巧,需要的朋友可以參考下2016-10-10Android Studio實現(xiàn)補(bǔ)間動畫
這篇文章主要為大家詳細(xì)介紹了Android Studio實現(xiàn)補(bǔ)間動畫,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-11-11