如何在Android上创build一个循环的进度条,在它上面旋转?

我正在尝试创build一个四舍五入的进度条。 这是我想要实现的

有一个灰色的背景环。 最重要的是,会出现一个蓝色的进度条,它以60或任何数量的秒数从0到360的循环path移动。

在这里输入图像说明

这是我的示例代码。

<ProgressBar android:id="@+id/ProgressBar" android:layout_width="match_parent" android:layout_height="match_parent" style="?android:attr/progressBarStyleLarge" android:indeterminateDrawable="@drawable/progressBarBG" android:progress="50" /> 

要做到这一点,在可绘制的“progressBarBG”中,我创build了一个图层列表,在图层列表中,我给出了两个项目,如图所示。

 <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@android:id/background"> <shape android:shape="ring" android:innerRadius="64dp" android:thickness="8dp" android:useLevel="false"> <solid android:color="@color/grey" /> </shape> </item> <item android:id="@android:id/progress"> <clip> <shape android:shape="ring" android:innerRadius="64dp" android:thickness="8dp" android:useLevel="false"> <solid android:color="@color/blue" /> </shape> </clip> </item> 

现在,第一个灰色的戒指生成的很好。 然而,蓝色的圆环从drawable的左边开始,就像线性进度条一样。 这是如何显示在50%的进展与红色箭头显示方向。

在这里输入图像说明

我想按预期的方式在循环path中移动蓝色的进度条。

这是我的两个解决scheme。

简短的回答:

我不是创build一个layer-list ,而是将它分成两个文件。 一个用于ProgressBar ,一个用于背景。

这是ProgressDrawable文件(@drawable文件夹): circular_progress_bar.xml

 <?xml version="1.0" encoding="utf-8"?> <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:fromDegrees="270" android:toDegrees="270"> <shape android:innerRadiusRatio="2.5" android:shape="ring" android:thickness="1dp" android:useLevel="true"><!-- this line fixes the issue for lollipop api 21 --> <gradient android:angle="0" android:endColor="#007DD6" android:startColor="#007DD6" android:type="sweep" android:useLevel="false" /> </shape> </rotate> 

这是它的background (@drawable文件夹): circle_shape.xml

 <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="ring" android:innerRadiusRatio="2.5" android:thickness="1dp" android:useLevel="false"> <solid android:color="#CCC" /> </shape> 

在最后,在你工作的布局里面:

 <ProgressBar android:id="@+id/progressBar" android:layout_width="200dp" android:layout_height="200dp" android:indeterminate="false" android:progressDrawable="@drawable/circular_progress_bar" android:background="@drawable/circle_shape" style="?android:attr/progressBarStyleHorizontal" android:max="100" android:progress="65" /> 

结果如下:

在这里输入图像说明

长答案:

View类的一个子类,一个自定义视图

在这里输入图像说明

这是github上的完整项目

我用简单的方法完成了:

请检查相同的屏幕截图。

CustomProgressBarActivity.java

 public class CustomProgressBarActivity extends AppCompatActivity { private TextView txtProgress; private ProgressBar progressBar; private int pStatus = 0; private Handler handler = new Handler(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_custom_progressbar); txtProgress = (TextView) findViewById(R.id.txtProgress); progressBar = (ProgressBar) findViewById(R.id.progressBar); new Thread(new Runnable() { @Override public void run() { while (pStatus <= 100) { handler.post(new Runnable() { @Override public void run() { progressBar.setProgress(pStatus); txtProgress.setText(pStatus + " %"); } }); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } pStatus++; } } }).start(); } } 

activity_custom_progressbar.xml

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" 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" tools:context="com.skholingua.android.custom_progressbar_circular.MainActivity" > <RelativeLayout android:layout_width="wrap_content" android:layout_centerInParent="true" android:layout_height="wrap_content"> <ProgressBar android:id="@+id/progressBar" style="?android:attr/progressBarStyleHorizontal" android:layout_width="250dp" android:layout_height="250dp" android:layout_centerInParent="true" android:indeterminate="false" android:max="100" android:progress="0" android:progressDrawable="@drawable/custom_progressbar_drawable" android:secondaryProgress="0" /> <TextView android:id="@+id/txtProgress" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/progressBar" android:layout_centerInParent="true" android:textAppearance="?android:attr/textAppearanceSmall" /> </RelativeLayout> </RelativeLayout> 

custom_progressbar_drawable.xml

 <?xml version="1.0" encoding="utf-8"?> <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:fromDegrees="-90" android:pivotX="50%" android:pivotY="50%" android:toDegrees="270" > <shape android:shape="ring" android:useLevel="false" > <gradient android:centerY="0.5" android:endColor="#FA5858" android:startColor="#0099CC" android:type="sweep" android:useLevel="false" /> </shape> </rotate> 

希望这会帮助你。

我已经在我的博客demonuts.com上写了详细的android环境进度条 示例 。 你也可以喜欢完整的源代码和解释。

下面是我如何在没有任何库的情况下在纯代码中使用百分比圆形循环进度条。

在这里输入图像说明

首先创build一个名为circular.xml的可绘制文件

 <?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@android:id/secondaryProgress"> <shape android:innerRadiusRatio="6" android:shape="ring" android:thicknessRatio="20.0" android:useLevel="true"> <gradient android:centerColor="#999999" android:endColor="#999999" android:startColor="#999999" android:type="sweep" /> </shape> </item> <item android:id="@android:id/progress"> <rotate android:fromDegrees="270" android:pivotX="50%" android:pivotY="50%" android:toDegrees="270"> <shape android:innerRadiusRatio="6" android:shape="ring" android:thicknessRatio="20.0" android:useLevel="true"> <rotate android:fromDegrees="0" android:pivotX="50%" android:pivotY="50%" android:toDegrees="360" /> <gradient android:centerColor="#00FF00" android:endColor="#00FF00" android:startColor="#00FF00" android:type="sweep" /> </shape> </rotate> </item> </layer-list> 

现在在您的activity_main.xml添加以下内容:

  <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/dialog" tools:context="com.example.parsaniahardik.progressanimation.MainActivity"> <ProgressBar android:id="@+id/circularProgressbar" style="?android:attr/progressBarStyleHorizontal" android:layout_width="250dp" android:layout_height="250dp" android:indeterminate="false" android:max="100" android:progress="50" android:layout_centerInParent="true" android:progressDrawable="@drawable/circular" android:secondaryProgress="100" /> <ImageView android:layout_width="90dp" android:layout_height="90dp" android:background="@drawable/whitecircle" android:layout_centerInParent="true"/> <TextView android:id="@+id/tv" android:layout_width="250dp" android:layout_height="250dp" android:gravity="center" android:text="25%" android:layout_centerInParent="true" android:textColor="@color/colorPrimaryDark" android:textSize="20sp" /> </RelativeLayout> 

activity_main.xml我使用了一个带有白色背景的圆形图像,以百分比forms显示白色背景。 这是图像:

在这里输入图像说明

您可以更改此图像的颜色以设置百分比文字的自定义颜色。

现在,最后将下面的代码添加到MainActivity.java

 import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.os.Handler; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.animation.DecelerateInterpolator; import android.widget.ProgressBar; import android.widget.TextView; public class MainActivity extends AppCompatActivity { int pStatus = 0; private Handler handler = new Handler(); TextView tv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Resources res = getResources(); Drawable drawable = res.getDrawable(R.drawable.circular); final ProgressBar mProgress = (ProgressBar) findViewById(R.id.circularProgressbar); mProgress.setProgress(0); // Main Progress mProgress.setSecondaryProgress(100); // Secondary Progress mProgress.setMax(100); // Maximum Progress mProgress.setProgressDrawable(drawable); /* ObjectAnimator animation = ObjectAnimator.ofInt(mProgress, "progress", 0, 100); animation.setDuration(50000); animation.setInterpolator(new DecelerateInterpolator()); animation.start();*/ tv = (TextView) findViewById(R.id.tv); new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub while (pStatus < 100) { pStatus += 1; handler.post(new Runnable() { @Override public void run() { // TODO Auto-generated method stub mProgress.setProgress(pStatus); tv.setText(pStatus + "%"); } }); try { // Sleep for 200 milliseconds. // Just to display the progress slowly Thread.sleep(8); //thread will take approx 1.5 seconds to finish } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } } 

如果你想制作水平的进度条,请点击这个链接,它有许多有价值的例子与源代码:
http://www.skholingua.com/android-basic/user-interface/form-widgets/progressbar

在GitHub的 CircularProgressBar 实现了一个开源库,它可以完成你想要的最简单的方法:

Gif演示CircularProgressBar

用法

要制作一个循环的ProgressBar,请在您的布局XML中添加CircularProgressBar ,并在投影仪中添加CircularProgressBar库 ,或者也可以通过Gradle获取它:

 compile 'com.mikhaellopez:circularprogressbar:1.0.0' 

XML

 <com.mikhaellopez.circularprogressbar.CircularProgressBar android:layout_width="wrap_content" android:layout_height="wrap_content" app:background_progressbar_color="#FFCDD2" app:background_progressbar_width="5dp" app:progressbar_color="#F44336" app:progressbar_width="10dp" /> 

您必须在您的XML中使用以下属性来更改您的CircularProgressBar。

属性:

  • app:progress (整数)>>默认0
  • app:progressbar_color (color)>> default BLACK
  • app:background_progressbar_color (color)>>默认为灰色
  • app:progressbar_width (维度)>>默认7dp
  • app:background_progressbar_width (维度)>>默认的3dP

JAVA

 CircularProgressBar circularProgressBar = (CircularProgressBar)findViewById(R.id.yourCircularProgressbar); circularProgressBar.setColor(ContextCompat.getColor(this, R.color.progressBarColor)); circularProgressBar.setBackgroundColor(ContextCompat.getColor(this, R.color.backgroundProgressBarColor)); circularProgressBar.setProgressBarWidth(getResources().getDimension(R.dimen.progressBarWidth)); circularProgressBar.setBackgroundProgressBarWidth(getResources().getDimension(R.dimen.backgroundProgressBarWidth)); int animationDuration = 2500; // 2500ms = 2,5s circularProgressBar.setProgressWithAnimation(65, animationDuration); // Default duration = 1500ms 

叉或在这里下载这个库>> https://github.com/lopspower/CircularProgressBar

我是新的,所以我不能发表评论,但认为分享懒惰的修复。 我也使用Pedram原来的方法,只是遇到了同样的棒棒糖问题。 但是另一篇文章中的alanv有一个修复方法。 它在API21中的一些错误或疏忽。 从字面上看,只需将android:useLevel="true"到您的循环进度xml即可。 Pedram的新方法仍然是正确的解决scheme,但我只是认为我也分享了懒散的解决scheme。

https://github.com/passsy/android-HoloCircularProgressBar是一个库的一个例子,这样做。; 正如Tenfour04所说的那样,它必须是有点习惯的,因为这不是直接支持的。 如果这个库不能像你所希望的那样工作,你可以将它分叉并修改细节使其符合你的喜好。 如果你实现了其他人可以重用的东西,你甚至可以提交一个拉取请求来重新合并!

试试这个方法来创build一个位图并将其设置为图像视图。

 private void circularImageBar(ImageView iv2, int i) { Bitmap b = Bitmap.createBitmap(300, 300,Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(b); Paint paint = new Paint(); paint.setColor(Color.parseColor("#c4c4c4")); paint.setStrokeWidth(10); paint.setStyle(Paint.Style.STROKE); canvas.drawCircle(150, 150, 140, paint); paint.setColor(Color.parseColor("#FFDB4C")); paint.setStrokeWidth(10); paint.setStyle(Paint.Style.FILL); final RectF oval = new RectF(); paint.setStyle(Paint.Style.STROKE); oval.set(10,10,290,290); canvas.drawArc(oval, 270, ((i*360)/100), false, paint); paint.setStrokeWidth(0); paint.setTextAlign(Align.CENTER); paint.setColor(Color.parseColor("#8E8E93")); paint.setTextSize(140); canvas.drawText(""+i, 150, 150+(paint.getTextSize()/3), paint); iv2.setImageBitmap(b); } 

@Pedram,你以前的解决scheme在棒棒糖中工作得很好(而且比新的更好,因为它在任何地方都是可用的,包括在远程视图中),只需将你的circular_progress_bar.xml代码更改为:

 <?xml version="1.0" encoding="utf-8"?> <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:fromDegrees="270" android:toDegrees="270"> <shape android:innerRadiusRatio="2.5" android:shape="ring" android:thickness="1dp" android:useLevel="true"> <!-- Just add this line --> <gradient android:angle="0" android:endColor="#007DD6" android:startColor="#007DD6" android:type="sweep" android:useLevel="false" /> </shape> </rotate> 
 package com.example.ankitrajpoot.myapplication; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.ProgressBar; public class MainActivity extends Activity { private ProgressBar spinner; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); spinner=(ProgressBar)findViewById(R.id.progressBar); spinner.setVisibility(View.VISIBLE); } } <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/loadingPanel" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center"> <ProgressBar android:id="@+id/progressBar" android:layout_width="48dp" style="?android:attr/progressBarStyleLarge" android:layout_height="48dp" android:indeterminateDrawable="@drawable/circular_progress_bar" android:indeterminate="true" /> </RelativeLayout> <?xml version="1.0" encoding="utf-8"?> <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:pivotX="50%" android:pivotY="50%" android:fromDegrees="0" android:toDegrees="1080"> <shape android:shape="ring" android:innerRadiusRatio="3" android:thicknessRatio="8" android:useLevel="false"> <size android:width="56dip" android:height="56dip" /> <gradient android:type="sweep" android:useLevel="false" android:startColor="@android:color/transparent" android:endColor="#1e9dff" android:angle="0" /> </shape> </rotate>