自定义ProgressBar(一)

ProgressBar是一个非常重要组件。通常用于向用户显示耗时操作完成的百分比。主要包括水平和圆形两种类型。讲解之前首先来讲一下样式属性设置,这个在自定义里面是核心部分。   本文主要介绍ProgressBar的属性里面的 progressDrawable 和 indeterminateDrawable

一、常用属性

(一)关于style属性设置:安卓支持几种风格的进度条,通过style属性可以为ProgressBar设置指定风格,该属性可支持如下几个属性值:

  1. 安卓styles.xml里面的 8个,这8个兼容不同系统版本,一般都用这些style样式用的多

属性值

属性的含义

style="@android:style/Widget.ProgressBar"

style="@android:style/Widget.ProgressBar.Large"

大环形进度条

style="@android:style/Widget.ProgressBar.Small"

小环形进度条

style="@android:style/Widget.ProgressBar.Inverse"

普通大小的环形进度条

style="@android:style/Widget.ProgressBar.Large.Inverse"

大环形进度条

style="@android:style/Widget.ProgressBar.Small.Inverse"

小环形进度条

style="@android:style/Widget.ProgressBar.Small.Title"

标题栏环形进度条

style="@android:style/Widget.ProgressBar.Horizontal"

水平进度条

<style name="Widget.ProgressBar">
    <item name="indeterminateOnly">true</item>
    <item name="indeterminateDrawable">@drawable/progress_medium_white</item>
    <item name="indeterminateBehavior">repeat</item>
    <item name="indeterminateDuration">3500</item>
    <item name="minWidth">48dip</item>
    <item name="maxWidth">48dip</item>
    <item name="minHeight">48dip</item>
    <item name="maxHeight">48dip</item>
    <item name="mirrorForRtl">false</item>
</style>

<style name="Widget.ProgressBar.Large">
    <item name="indeterminateDrawable">@drawable/progress_large_white</item>
    <item name="minWidth">76dip</item>
    <item name="maxWidth">76dip</item>
    <item name="minHeight">76dip</item>
    <item name="maxHeight">76dip</item>
</style>

<style name="Widget.ProgressBar.Small">
    <item name="indeterminateDrawable">@drawable/progress_small_white</item>
    <item name="minWidth">16dip</item>
    <item name="maxWidth">16dip</item>
    <item name="minHeight">16dip</item>
    <item name="maxHeight">16dip</item>
</style>

<style name="Widget.ProgressBar.Inverse">
    <item name="indeterminateDrawable">@drawable/progress_medium</item>
</style>

<style name="Widget.ProgressBar.Large.Inverse">
    <item name="indeterminateDrawable">@drawable/progress_large</item>
</style>

<style name="Widget.ProgressBar.Small.Inverse">
    <item name="indeterminateDrawable">@drawable/progress_small</item>
</style>

<style name="Widget.ProgressBar.Small.Title">
    <item name="indeterminateDrawable">@drawable/progress_small_titlebar</item>
</style>

<style name="Widget.ProgressBar.Horizontal">
    <item name="indeterminateOnly">false</item>
    <item name="progressDrawable">@drawable/progress_horizontal</item>
    <item name="indeterminateDrawable">@drawable/progress_indeterminate_horizontal</item>
    <item name="minHeight">20dip</item>
    <item name="maxHeight">20dip</item>
    <item name="mirrorForRtl">true</item>
</style>

2.styles_holo.xml里面的 16个,其中Widget.Holo.开头的有8个,Widget.Holo.Light.开头的有8个

----------------------------------------------- Widget.Holo.开头的 ------------------------------------------------------

<style name="Widget.Holo.ProgressBar" parent="Widget.ProgressBar">
    <item name="indeterminateDrawable">@drawable/progress_medium_holo</item>
</style>

<style name="Widget.Holo.ProgressBar.Horizontal" parent="Widget.ProgressBar.Horizontal">
    <item name="progressDrawable">@drawable/progress_horizontal_holo_dark</item>
    <item name="indeterminateDrawable">@drawable/progress_indeterminate_horizontal_holo</item>
    <item name="minHeight">16dip</item>
    <item name="maxHeight">16dip</item>
</style>

<style name="Widget.Holo.ProgressBar.Small" parent="Widget.ProgressBar.Small">
    <item name="indeterminateDrawable">@drawable/progress_small_holo</item>
</style>

<style name="Widget.Holo.ProgressBar.Small.Title" />

<style name="Widget.Holo.ProgressBar.Large" parent="Widget.ProgressBar.Large">
    <item name="indeterminateDrawable">@drawable/progress_large_holo</item>
</style>

<style name="Widget.Holo.ProgressBar.Inverse" />

<style name="Widget.Holo.ProgressBar.Small.Inverse" />

<style name="Widget.Holo.ProgressBar.Large.Inverse" />

--------------------------------------------- Widget.Holo.Light.开头的 ----------------------------------------------------

<style name="Widget.Holo.Light.ProgressBar" parent="Widget.Holo.ProgressBar" />

<style name="Widget.Holo.Light.ProgressBar.Horizontal" parent="Widget.Holo.ProgressBar.Horizontal">
    <item name="progressDrawable">@drawable/progress_horizontal_holo_light</item>
</style>

<style name="Widget.Holo.Light.ProgressBar.Small" parent="Widget.Holo.ProgressBar.Small" />

<style name="Widget.Holo.Light.ProgressBar.Small.Title" parent="Widget.Holo.ProgressBar.Small.Title" />

<style name="Widget.Holo.Light.ProgressBar.Large" parent="Widget.Holo.ProgressBar.Large" />

<style name="Widget.Holo.Light.ProgressBar.Inverse" parent="Widget.Holo.ProgressBar.Inverse" />

<style name="Widget.Holo.Light.ProgressBar.Small.Inverse" parent="Widget.Holo.ProgressBar.Small.Inverse" />

<style name="Widget.Holo.Light.ProgressBar.Large.Inverse" parent="Widget.Holo.ProgressBar.Large.Inverse" />

3.styles_material.xml里面的 16个,其中Widget.Material.开头的有8个,Widget.Material.Light.开头的有8个

----------------------------------------------- Widget.Material.开头的 ------------------------------------------------------

<style name="Widget.Material.ProgressBar" parent="Widget.ProgressBar">
    <item name="indeterminateDrawable">@drawable/progress_medium_material</item>
</style>

<style name="Widget.Material.ProgressBar.Inverse"/>

<style name="Widget.Material.ProgressBar.Horizontal" parent="Widget.ProgressBar.Horizontal">
    <item name="progressDrawable">@drawable/progress_horizontal_material</item>
    <item name="indeterminateDrawable">@drawable/progress_indeterminate_horizontal_material</item>
    <item name="minHeight">16dip</item>
    <item name="maxHeight">16dip</item>
</style>

<style name="Widget.Material.ProgressBar.Small" parent="Widget.ProgressBar.Small">
    <item name="indeterminateDrawable">@drawable/progress_small_material</item>
</style>

<style name="Widget.Material.ProgressBar.Small.Inverse"/>
<style name="Widget.Material.ProgressBar.Small.Title"/>

<style name="Widget.Material.ProgressBar.Large" parent="Widget.ProgressBar.Large">
    <item name="indeterminateDrawable">@drawable/progress_large_material</item>
</style>

<style name="Widget.Material.ProgressBar.Large.Inverse"/>

-------------------------------------------- Widget.Material.Light.开头的 ---------------------------------------------------

<style name="Widget.Material.Light.ProgressBar" parent="Widget.Material.ProgressBar"/>
<style name="Widget.Material.Light.ProgressBar.Horizontal" parent="Widget.Material.ProgressBar.Horizontal"/>
<style name="Widget.Material.Light.ProgressBar.Small" parent="Widget.Material.ProgressBar.Small"/>
<style name="Widget.Material.Light.ProgressBar.Small.Title" parent="Widget.Material.ProgressBar.Small.Title"/>
<style name="Widget.Material.Light.ProgressBar.Large" parent="Widget.Material.ProgressBar.Large"/>
<style name="Widget.Material.Light.ProgressBar.Inverse" parent="Widget.Material.ProgressBar.Inverse"/>
<style name="Widget.Material.Light.ProgressBar.Small.Inverse" parent="Widget.Material.ProgressBar.Small.Inverse"/>
<style name="Widget.Material.Light.ProgressBar.Large.Inverse" parent="Widget.Material.ProgressBar.Large.Inverse"/>

4.styles_device_default.xml里面的13个,其中Widget.DeviceDefault.开头的有5个, Widget.DeviceDefault.Light.开头的有8个。

------------------------------------------- Widget.DeviceDefault..开头的 --------------------------------------------------

<style name="Widget.DeviceDefault.ProgressBar" parent="Widget.Material.ProgressBar"/>

<style name="Widget.DeviceDefault.ProgressBar.Horizontal" parent="Widget.Material.ProgressBar.Horizontal"/>

<style name="Widget.DeviceDefault.ProgressBar.Small" parent="Widget.Material.ProgressBar.Small"/>

<style name="Widget.DeviceDefault.ProgressBar.Small.Title" parent="Widget.Material.ProgressBar.Small.Title"/>

<style name="Widget.DeviceDefault.ProgressBar.Large" parent="Widget.Material.ProgressBar.Large"/>

---------------------------------------- Widget.DeviceDefault.Light.开头的 -----------------------------------------------

<style name="Widget.DeviceDefault.Light.ProgressBar"
    parent="Widget.Material.Light.ProgressBar"/>

<style name="Widget.DeviceDefault.Light.ProgressBar.Horizontal" 
    parent="Widget.Material.Light.ProgressBar.Horizontal"/>

<style name="Widget.DeviceDefault.Light.ProgressBar.Small" 
    parent="Widget.Material.Light.ProgressBar.Small"/>

<style name="Widget.DeviceDefault.Light.ProgressBar.Small.Title" 
    parent="Widget.Material.Light.ProgressBar.Small.Title"/>

<style name="Widget.DeviceDefault.Light.ProgressBar.Large" 
    parent="Widget.Material.Light.ProgressBar.Large"/>

<style name="Widget.DeviceDefault.Light.ProgressBar.Inverse" 
    parent="Widget.Material.Light.ProgressBar.Inverse"/>

<style name="Widget.DeviceDefault.Light.ProgressBar.Small.Inverse" 
    parent="Widget.Material.Light.ProgressBar.Small.Inverse"/>

<style name="Widget.DeviceDefault.Light.ProgressBar.Large.Inverse" 
    parent="Widget.Material.Light.ProgressBar.Large.Inverse"/>
(二)其他属性

属性值

描述

android:max=""

进度条最大值

android:progress=""

进度条已完成值

android:secondaryProgress=""

二级进度值,值介于0到max。该进度在主进度和背景之间。比如用于网络播放视频时,二级进度用于表示缓冲进度,主进度用于表示播放进度。

android:animationResolution

超时的动画帧之间的毫秒 ;必须是一个整数值,如“100”。(已经被舍弃了,现在都不用了。)

android:progressDrawable=""

设置进度条轨道对应的drawable对象

android:indeterminate=""

是否允许使用不确定模式,该属性设置为true,表示设置进度条不精确显示进度,在不确定模式下,进度条动画无限循环

android:indeterminateDrawable=""

定义不确定模式是否可拉

android:indeterminateDuration=""

时间不定的动画

android:indeterminateBehavior=""

定义当进度达到最大时,不确定模式的表现;该值必须为repeat或者cycle,repeat表示进度从0重新开始;cycle表示进度保持当前值,并且回到0

android:indeterminateOnly=""

限制为不定模式

android:indeterminateTint=""

android:indeterminateTintMode=""

二、水平的ProgressBar

1.首先是布局代码:

  <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#3C7793"
    android:orientation="vertical">

    <ProgressBar
        android:id="@+id/progressBar1"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_margin="10dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:progress="0"
        android:secondaryProgress="100"
        android:progressDrawable="@drawable/progressbar_line" />
</LinearLayout>

2.再看drawable目录下的progressbar_line.xml是怎么定义的:(第一个item是背景,第二个item是二级进度值,一般用于视频的缓冲,最后一个是显示的进度)

  <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@android:id/background">
        <shape>
            <corners android:radius="5dip" />
            <gradient
                android:startColor="#ff9d9e9d"
                android:centerColor="#ff5a5d5a"
                android:centerY="0.75"
                android:endColor="#ff747674"
                android:angle="0"
                />
        </shape>
    </item>

    <item android:id="@android:id/secondaryProgress">
        <clip>
            <shape>
                <corners android:radius="5dip" />
                <gradient
                    android:startColor="#80ffd300"
                    android:centerColor="#80ffb600"
                    android:centerY="0.75"
                    android:endColor="#a0ffcb00"
                    android:angle="0"
                    />
            </shape>
        </clip>
    </item>

    <item android:id="@android:id/progress">
        <clip>
            <shape>
                <corners
                    android:radius="5dip" />
                <gradient
                    android:startColor="#80ff0000"
                    android:endColor="#8000ff00"
                    android:angle="0" />
            </shape>
        </clip>
    </item>
  </layer-list>

3.代码里面控制进度的显示,新建一个线程,重写runnable,在run方法里面去模拟执行耗时操作,通过handler发消息给主线程,主线程拿到消息之后更新UI.

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.widget.ProgressBar;

public class MainActivity extends AppCompatActivity {
   
    private ProgressBar progressBar1;

    //在这里处理更新进度条
    private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 0x0001:
                    progressBar1.setProgress(msg.arg1);
                    //如果进度小于100,则延迟100毫秒之后重复执行runnable
                    if(msg.arg1<100){
                        mHandler.postDelayed(r, 100);
                    }else{
                        //否则,都置零,线程重新执行
                        progressBar1.setProgress(0);
                        mHandler.post(r);
                    }
                    break;
            }
        }
    };

    Runnable r = new Runnable() {
        int currentProgress = 0;
        @Override
        public void run() {
            Message msg = new Message();
            msg.what = 0x0001;
            currentProgress = progressBar1.getProgress()+1;
            progressBar1.setProgress(currentProgress);
            msg.arg1 = currentProgress;
            mHandler.sendMessage(msg);
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);

        progressBar1 = (ProgressBar) findViewById(R.id.progressBar1);
        progressBar1.setProgressDrawable(getResources().getDrawable(R.drawable.progressbar_line));

        if(progressBar1.getProgress() < progressBar1.getMax()){
            // 把r加入到线程队列,然后线程队列里就开始执行runnable对象中的run()
            mHandler.post(r);
        }else{//不用的时候,就把r从线程队列移除,这是一个小的性能优化
            mHandler.removeCallbacks(r);
        }
    }
}

三、圆形的ProgressBar

1.先来看看布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#3C7793"
android:orientation="vertical">

    <ProgressBar
        android:id="@+id/loadProgressBar"
        style="@android:style/Widget.ProgressBar"
        android:layout_margin="10dp"
        android:indeterminateDrawable="@drawable/progressbar_round"
        android:layout_width="100dp"
        android:layout_height="100dp" />
</LinearLayout>

2.再看看drawable目录下的progressbar_round.xml

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="0"
    android:pivotX="50%"
    android:pivotY="50%"
    android:toDegrees="360">

    <shape
        android:innerRadiusRatio="3"
        android:shape="ring"
        android:thicknessRatio="10"
        android:useLevel="false">

        <gradient
            android:centerColor="#FFFFFF"
            android:centerY="0.50"
            android:endColor="#FFFF00"
            android:startColor="#00FFFF"
            android:type="sweep"
            android:useLevel="false" />
    </shape>
</rotate>

效果图如下:

ProgressBar演示.gif

下一篇我们重点讲解如何写一个View继承ProgressBar,实现各种吊炸天的效果。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏码神联盟

碎片化 | 第四阶段-41-struts2字节流生成验证码-视频

如清晰度低,可转PC网页观看高清版本: http://v.qq.com/x/page/r056700jckx.html 验证码实现 需求: 在登录的页面,增...

29790
来自专栏前端菜鸟变老鸟

常见的html、css以及javascript兼容方案

    浏览器兼容性一直是一个前端开发人员不可避免的大问题,这篇文章主要列举了html、css以及javascript中一些常见的兼容性问题以及对应的解决方案。

9910
来自专栏Flutter&Dart

Flutter之DataTable使用详解

57330
来自专栏Google Dart

Flutte部件目录-基本部件(三) 顶

要显示snackbar或持久底部表,请通过Scaffold.of获取当前BuildContext的ScaffoldState,然后使用ScaffoldState...

30610
来自专栏Coco的专栏

【CSS进阶】原生JS getComputedStyle等方法解析

24050
来自专栏向治洪

微信小程序之picker组件

作为移动端的分发入口,微信小程序虽然没有当初期望的那么火,但是却是一个不能忽视的入口。撇开微信小程序对于腾讯生态的原因不说,微信小程序对于开发还是很方便的,特别...

87450
来自专栏章鱼的慢慢技术路

用Python中的tkinter模块作图(续)

31570
来自专栏前端小作坊

CSS3着重符及其fallback

在中文里面,我们一般会在文字下方加上圆形符号。在日语中会在文字上方加上小顿号。在CSS3中如下属性可以控制着重符号:

11620
来自专栏前端儿

编写高质量 JavaScript -- 知识点小记

此番改善之后,匿名function里面的变量作用域不再是window,而是局限在函数内。

19910
来自专栏向治洪

React Native之TextInput组件实现联想输入

TextInput组件是最基本的组件,相关介绍请查看TextInput组件介绍 输入框组件属性 输入框组件的主要属性如下: autoCapitalize : ...

242100

扫码关注云+社区

领取腾讯云代金券