Android自定义环形LoadingView效果
这篇文章主要为大家详细介绍了Android自定义环形LoadingView效果的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
最近项目有要用到环形的进度条,Github上有一个类似的DashedCircularProgress控件,但是他画的进度是通过设置画笔的虚线效果来实现间隔的:progressPaint.setPathEffect(new DashPathEffect(new float[]{dashWith, dashSpace}, dashSpace));如果内层还有一层圆环,在动态设置时,内层和外层有细微的偏差.于是我在原有基础上改了一个,实现了我要的效果(设置进度时可以选择加动画或者不加动画):
控件实现:
这个控件继承RelativeLayout,在onDraw时做了两件事:
1、先画出底部的黑色环形;
2、按照当时的进度值画出对应比例的外层绿色环形.
对外提供一个接口,回调当前进度值:
public interface OnValueChangeListener { void onValueChange(float value); }
核心绘制类:
InternalCirclePainterImp2,绘制内层的黑色的环形:
/** * @author Chuck */ public class InternalCirclePainterImp2 implements InternalCirclePainter { private RectF internalCircle;//画出圆弧时,圆弧的外切矩形 private Paint internalCirclePaint; private int color; private float startAngle = 270f; int arcQuantity=100;//等分(圆弧加间隔),比如arcQuantity=100时,表示将有100个圆弧,和100个空白间隔 float ratio=0.5f;//每段圆弧与圆弧加间隔之和的比例,ratio=0.5表示每个圆弧与相邻的间隔弧度比是1:1 private int width; private int height; private int internalStrokeWidth = 48;//圆环宽度 public InternalCirclePainterImp2(int color, int progressStrokeWidth, int arcQuantity,float ratio) { this.color = color; this.internalStrokeWidth = progressStrokeWidth; this.arcQuantity = arcQuantity; if(ratio>0&&ratio<1){ this.ratio = ratio; } init(); } private void init() { initExternalCirclePainter(); } private void initExternalCirclePainter() { internalCirclePaint = new Paint(); internalCirclePaint.setAntiAlias(true); internalCirclePaint.setStrokeWidth(internalStrokeWidth); internalCirclePaint.setColor(color); internalCirclePaint.setStyle(Paint.Style.STROKE); } //圆弧外切矩形 private void initExternalCircle() { internalCircle = new RectF(); float padding = internalStrokeWidth * 0.5f; internalCircle.set(padding, padding , width - padding, height - padding); initExternalCirclePainter(); } @Override public void draw(Canvas canvas) { float eachAngle=360f/arcQuantity; float eachArcAngle=eachAngle*ratio; for(int i=0;i<arcQuantity*2;i++){ if(i%2==0){//遇到偶数就画圆弧,基数则跳过 canvas.drawArc(internalCircle, startAngle+eachAngle*i/2, eachArcAngle, false, internalCirclePaint); } else{ continue; } } } public void setColor(int color) { this.color = color; internalCirclePaint.setColor(color); } @Override public int getColor() { return color; } @Override public void onSizeChanged(int height, int width) { this.width = width; this.height = height; initExternalCircle(); } }
ProgressPainterImp2,绘制内层的黑色的环形:
/** * @author Chuck */ public class ProgressPainterImp2 implements ProgressPainter { private RectF progressCircle; private Paint progressPaint; private int color = Color.RED; private float startAngle = 270f; private int internalStrokeWidth = 48; private float min; private float max; private int width; private int height; private int currentPecent;//当前的百分比 int arcQuantity=100;//等分(圆弧加间隔),比如arcQuantity=100时,表示将有100个圆弧,和100个空白间隔 float ratio=0.5f;//每段圆弧与圆弧加间隔之和的比例,ratio=0.5表示每个圆弧与相邻的间隔弧度比是1:1 public ProgressPainterImp2(int color, float min, float max, int progressStrokeWidth, int arcQuantity,float ratio) { this.color = color; this.min = min; this.max = max; this.internalStrokeWidth = progressStrokeWidth; this.arcQuantity = arcQuantity; this.ratio = ratio; init(); Log.e("ProgressPainterImp","构造函数执行"); } private void init() { initInternalCirclePainter(); } private void initInternalCirclePainter() { progressPaint = new Paint(); progressPaint.setAntiAlias(true); progressPaint.setStrokeWidth(internalStrokeWidth); progressPaint.setColor(color); progressPaint.setStyle(Paint.Style.STROKE); } //初始化外切的那个矩形 private void initInternalCircle() { progressCircle = new RectF(); float padding = internalStrokeWidth * 0.5f; progressCircle.set(padding, padding , width - padding, height - padding); initInternalCirclePainter(); } @Override public void draw(Canvas canvas) { float eachAngle=360f/arcQuantity; float eachArcAngle=eachAngle*ratio; int quantity=2*arcQuantity*currentPecent/100; for(int i=0;i<quantity;i++){ if(i%2==0){//遇到偶数就画圆弧,基数则跳过 canvas.drawArc(progressCircle, startAngle+eachAngle*i/2, eachArcAngle, false, progressPaint); } else{ continue; } } } public float getMin() { return min; } public void setMin(float min) { this.min = min; } public float getMax() { return max; } public void setMax(float max) { this.max = max; } public void setValue(float value) { this.currentPecent = (int) (( 100f * value) / max); } @Override public void onSizeChanged(int height, int width) { Log.e("ProgressPainterImp","onSizeChanged执行"); this.width = width; this.height = height; initInternalCircle(); } public int getColor() { return color; } public void setColor(int color) { this.color = color; progressPaint.setColor(color); } }
可以自定义的属性:
<declare-styleable name="CircularLoadingView"> <attr name="base_color" format="color" /> <!--内层圆环的颜色--> <attr name="progress_color" format="color" /><!--进度圆环的颜色--> <attr name="max" format="float" /><!--最小值--> <attr name="min" format="float" /><!--最大值--> <attr name="duration" format="integer" /><!--动画时长--> <attr name="progress_stroke_width" format="integer" /><!--圆环宽度--> <!--等分(圆弧加间隔),比如arcQuantity=100时,表示将有100个圆弧,和100个空白间隔--> <attr name="argQuantity" format="integer" /> <!--每段圆弧与圆弧加间隔之和的比例,ratio=0.5表示每个圆弧与相邻的间隔弧度比是1:1--> <attr name="ratio" format="float" /> </declare-styleable>
调用:
main_activity.xml:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" xmlns:custom="http://schemas.android.com/apk/res-auto" android:background="#ffffff" > <!--自定义控件,继承RelativeLayout--> <qdong.com.mylibrary.CircularLoadingView android:id="@+id/simple" custom:base_color="@color/pager_bg" custom:min="0" custom:max="100" custom:argQuantity="100" custom:ratio="0.6" custom:progress_color="@android:color/holo_green_light" custom:progress_icon="@mipmap/ic_launcher" custom:duration="1000" custom:progress_stroke_width="28" android:layout_centerInParent="true" android:layout_width="200dp" android:layout_height="200dp"> <RelativeLayout android:layout_centerInParent="true" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_centerInParent="true" android:textSize="20sp" android:layout_centerHorizontal="true" android:id="@+id/number" android:text="0" android:gravity="center" android:textColor="@color/pager_bg" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </RelativeLayout> </qdong.com.mylibrary.CircularLoadingView> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Set_Value" android:id="@+id/button" android:layout_alignParentBottom="true" android:layout_alignParentStart="true"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Animation" android:id="@+id/button3" android:layout_alignTop="@+id/button" android:layout_alignParentEnd="true"/> </RelativeLayout>
MainActivity:
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { try { mDashedCircularProgress.setValue(66);//没有动画的,直接设置 } catch (Exception e) { e.printStackTrace(); } } }); findViewById(R.id.button3).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { try { mDashedCircularProgress.setValue(0);//无动画,归零 mDashedCircularProgress.setValueWithAnimation(100,2000);//带动画 } catch (Exception e) { e.printStackTrace(); } } });
Github地址:https://github.com/506954774/AndroidCircularLoadingView
以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!
相关推荐:
Atas ialah kandungan terperinci Android自定义环形LoadingView效果. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas



Dalam beberapa hari kebelakangan ini, Ice Universe terus mendedahkan butiran mengenai Galaxy S25 Ultra, yang secara meluas dipercayai sebagai telefon pintar utama Samsung yang seterusnya. Antara lain, pembocor itu mendakwa bahawa Samsung hanya merancang untuk membawa satu peningkatan kamera

OnLeaks kini telah bekerjasama dengan Android Headlines untuk memberikan pandangan pertama pada Galaxy S25 Ultra, beberapa hari selepas percubaan gagal untuk menjana lebih daripada $4,000 daripada pengikut X (dahulunya Twitter). Untuk konteks, imej pemaparan yang dibenamkan di bawah h

Di samping mengumumkan dua telefon pintar baharu, TCL juga telah mengumumkan tablet Android baharu yang dipanggil NXTPAPER 14, dan saiz skrinnya yang besar adalah salah satu nilai jualannya. NXTPAPER 14 menampilkan versi 3.0 jenama tandatangan TCL panel LCD matte

Vivo Y300 Pro baru sahaja didedahkan sepenuhnya, dan ia merupakan salah satu telefon Android jarak pertengahan paling tipis dengan bateri yang besar. Tepatnya, telefon pintar ini hanya tebal 7.69 mm tetapi mempunyai bateri 6,500 mAh. Ini adalah kapasiti yang sama seperti yang dilancarkan baru-baru ini

Samsung belum menawarkan sebarang petunjuk lagi tentang bila ia akan mengemas kini siri telefon pintar Edisi Peminat (FE). Seperti sedia ada, Galaxy S23 FE kekal sebagai edisi terbaharu syarikat, telah dibentangkan pada awal Oktober 2023. Walau bagaimanapun, banyak

Dalam beberapa hari kebelakangan ini, Ice Universe terus mendedahkan butiran mengenai Galaxy S25 Ultra, yang secara meluas dipercayai sebagai telefon pintar utama Samsung yang seterusnya. Antara lain, pembocor itu mendakwa bahawa Samsung hanya merancang untuk membawa satu peningkatan kamera

Redmi Note 14 Pro Plus kini rasmi sebagai pengganti langsung kepada Redmi Note 13 Pro Plus tahun lepas (sekira $375 di Amazon). Seperti yang dijangkakan, Redmi Note 14 Pro Plus mengetuai siri Redmi Note 14 bersama Redmi Note 14 dan Redmi Note 14 Pro. Li

Jenama OnePlus iQOO mempunyai kitaran produk 2023-4 yang mungkin hampir tamat; Namun begitu, jenama itu telah mengisytiharkan bahawa ia belum selesai dengan siri Z9nya. Varian Turbo+yang terakhir, dan mungkin paling akhir, baru sahaja diumumkan seperti yang diramalkan. T
