如何在安卓中实现材料设计的圆形进度条

78

我想制作一个类似于Inbox by Gmail Android应用程序中的材料设计圆形进度条。我该如何实现它(在早期版本的Android系统中)?

我正在尝试实现类似于此效果。 Inbox by Gmail材料设计圆形进度条


1
https://github.com/passsy/android-HoloCircularProgressBar - Naveen Tamrakar
1
这是一个对程序员非常有用的链接:https://github.com/Sefford/CircularProgressDrawable。 - Naveen Tamrakar
尝试使用由Mohammed AG提供的xposed模块平滑系统进度条,正如Prajwal所建议的那样。 - kenorb
@Zapnologica 他们的示例仅适用于Android Lollipop设备,加载旋转器内置于Lollipop中,但我正在寻找将其移植回较低版本的Android的方法。 - cozeJ4
1
@cozeJ4 我希望支持库能够提供这样的功能。 - Zapnologica
9个回答

50
<ProgressBar
android:id="@+id/loading_spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminateTintMode="src_atop"
android:indeterminateTint="@color/your_customized_color"
android:layout_gravity="center" />

效果如下:

img


14
这在安卓5.0以下的设备上无法正常工作。在5.0以下的设备上,会使用不同的旋转图标。 - cozeJ4

26

优秀的材料设计圆形进度条实现(来自rahatarmanahmed/CircularProgressView),

<com.github.rahatarmanahmed.cpv.CircularProgressView
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/progress_view"
    android:layout_width="40dp"
    android:layout_height="40dp"
    app:cpv_indeterminate="true"/>

输入图像描述


嗨,Fahim,你所说的Native progressBar是什么意思?这是来自Android平台吗? 我想实现同样类型的对话框,最好是从Android本身或任何支持库中提供。 - cgr
@cgr Native ProgressBar 是使用 Android SDK 实现的进度条。如果您在两个不同的 Android 设备上运行此应用程序(例如:Jelly Beans 和 Lollipop),则会看到不同的进度条。请自行尝试。 - Filipe Brito
非常简单,谢谢。添加不透明的背景颜色最好的方法是什么?比如说,如果我想在一个更大的白色背景圆圈上放置一个黑色弧形圆圈,就像 Gmail 的指示器一样? - Mike Purcell

23

我已将三个Material Design进度可绘制对象向后移植到Android 4.0,可作为普通ProgressBar的即插即用替代品,外观完全相同。

这些可绘制对象还后移植了着色API(以及RTL支持),并使用?colorControlActivated作为默认的着色。为方便起见,引入了一个扩展ProgressBarMaterialProgressBar小部件。

DreaminginCodeZH/MaterialProgressBar

该项目还被afollestad/material-dialogs用于进度对话框。

在Android 4.4.4上:

Android 4.4.4

在Android 5.1.1上:

Android 5.1.1


1
感谢您的所有努力!非常棒的库!继续保持! - Filipe Brito
非常优雅的解决方案,在我看来是最好的。 - a.ch.
谢谢提供这个库!有没有办法改变旋转器的颜色? - Foobar
1
@Roymunson 请查看README文件和有关app:mpb_progressTint等的段落。 - Hai Zhang

19

使用 Material Components 库,您可以使用 CircularProgressIndicator

类似这样:

<com.google.android.material.progressindicator.CircularProgressIndicator
      android:indeterminate="true"          
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      app:indicatorColor="@array/progress_colors"
      app:indicatorSize="xxdp"
      app:indeterminateAnimationType="contiguous"/>

其中array/progress_colors是一个包含颜色的数组:

  <integer-array name="progress_colors">
    <item>@color/yellow_500</item>
    <item>@color/blue_700</item>
    <item>@color/red_500</item>
  </integer-array>

输入图像描述

注意:需要至少版本1.3.0


1
@StoychoAndreev 目前的 minSdk = 14 - Gabriele Mariotti
谢谢你的代码。但是这个类没有像“circularRadius”和“growMode”这样的属性。如果存在,请纠正我。 - NimaAzhd
@nIMaaZx 感谢您的反馈。它们被 app:indicatorSize="xxdp"app:showAnimationBehavior 替换了。 - Gabriele Mariotti
1
@GabrieleMariotti 再次感谢您的编辑。我想建议进行编辑,但它不允许编辑答案。 - NimaAzhd
1
@Web。请查看此链接:https://developer.android.com/guide/topics/resources/more-resources#IntegerArray - Gabriele Mariotti
显示剩余3条评论

17

更新

从2019年开始,您可以轻松使用Material Components库中的ProgressIndicatorWidget.MaterialComponents.ProgressIndicator.Circular.Indeterminate样式实现此目标。

有关更多详细信息,请查看以下Gabriele Mariotti的答案。

旧实现

这是一个很棒的材料设计圆形中间进度条的实现https://gist.github.com/castorflex/4e46a9dc2c3a4245a28e。该实现只缺少添加类似于Android应用程序收件箱中的各种颜色的功能,但它已经做得非常好了。


9
除了 cozeJ4 的答案外,这里有一个更新版的Gist

原版缺少导入,并且包含一些错误。这个更新版可以直接使用。


1
你能解释一下我们如何使用这个吗? - Devendra Singh
复制这些类,将包更改为您项目的包,并在布局中使用MaterialProgressBar作为视图,就这样。 - Dmide
但我想展示的是,当异步任务结束时,pro.bar aiso必须完成。 - Devendra Singh
哇!谢谢,老兄。使用com.rey.material库,你帮我避免了很多麻烦。 - M D P
你也有线性版本吗? - M D P

6

好的,现在我们有了VectorDrawableCompat,你可能只需要重复使用相同的可绘制对象。 - Teovald

5

我曾试图使用简单的xml实现此功能,但没有找到有用的答案,所以想出了这个方法。

这个方法在早期版本中也适用,并且与Material Design进度条非常接近。您只需要将此drawable用作ProgressBar布局中的indeterminate drawable即可。

<?xml version="1.0" encoding="utf-8"?><!--<layer-list>-->
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="0"
    android:toDegrees="360">
    <layer-list>
        <item>
            <rotate xmlns:android="http://schemas.android.com/apk/res/android"
                android:fromDegrees="-90"
                android:toDegrees="-90">
                <shape
                    android:innerRadiusRatio="2.5"
                    android:shape="ring"
                    android:thickness="2dp"
                    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>
        </item>
        <item>
            <rotate xmlns:android="http://schemas.android.com/apk/res/android"
                android:fromDegrees="0"
                android:toDegrees="270">
                <shape
                    android:innerRadiusRatio="2.6"
                    android:shape="ring"
                    android:thickness="4dp"
                    android:useLevel="true"><!-- this line fixes the issue for lollipop api 21 -->
                    <gradient
                        android:angle="0"
                        android:centerColor="#FFF"
                        android:endColor="#FFF"
                        android:startColor="#FFF"
                        android:useLevel="false" />
                </shape>
            </rotate>
        </item>
    </layer-list>
</rotate>

将上面的可绘制对象设置为ProgressBar如下:
  android:indeterminatedrawable="@drawable/above_drawable"

未知属性 android:indeterminatedrawable - appukrb
动画完全不同。 - Phate P

0

带有背景的加载器。

将其添加到您的布局中:

<androidx.constraintlayout.widget.ConstraintLayout
    android:id="@+id/loader"
    android:layout_width="35dp"
    android:layout_height="35dp"
    android:visibility="visible"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintTop_toTopOf="parent">

    <ImageView
        android:id="@+id/background_loader"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/background_loader"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toBottomOf="parent" />

    <ProgressBar
        android:id="@+id/spinner_loader"
        android:layout_width="31dp"
        android:layout_height="31dp"
        android:indeterminateTintMode="src_atop"
        android:indeterminateTint="@color/blue"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

然后将background_loader.xml文件添加到res/drawable目录中。
<?xml version="1.0" encoding="utf-8"?>
<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <solid android:color="#ffffff"/>
    <size android:width="35dp" android:height="35dp"/>
</shape>

在代码中管理加载器的可见性:

class MainActivity : AppCompatActivity() {
    private lateinit var loader: ConstraintLayout
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        loader = findViewById(R.id.loader)
        loader.visibility = View.VISIBLE
    }
}

结果:

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接