`
阅读更多

做过Android开发的同学应该都不会对这个控件陌生。主要是用来实现处理或加载进度的显示或者提示用户正在处理或加载数据。

基本来说就两种情况,一种是转圈的小菊花,一种是水平的进度条。

默认情况下ProgressBar是圆形的那种,如果你要设置成水平状的,需要加入style

style="?android:attr/progressBarStyleHorizontal"

这两种形式的默认效果都不是很理想,个人认为Google的UI真的是丑到家了,不知道3.0之前是不是没有请UI呢?开个玩笑...

 

下面我们来看看ProgressBar中的style。通过style来简单分析下ProgressBar

首先在你的工程的res/values/styles.xml文件中加入下面的代码:

<style 
        name="test" parent="@android:style/Widget.ProgressBar">
</style>

 这只是为了方便你查看源码而已(我使用的是Eclipse,鼠标移到Widget.ProgressBar上,按下ctrl键即可),如果你的IDE看不到源码,也没有关系,你可以直接到源码的目录下找到这个style(比如我的sdk目录):

 

E:\androidSDK\sdk\platforms\android-7\data\res\values\styles.xml

 

然后找到“Widget.ProgressBar”即可:

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

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

 我把其中的Widget.ProgressBarWidget.ProgressBar.Horizontal拿出来给大家看看。

indeterminate意思是“模糊的,不明确的”,而 android:indeterminateOnly这个属性如果设置为true,表示的是这个ProgressBar是模糊的,不明确的,也就是说,当前它并没有体现出具体的进度,只是一个小菊花在转(Widget.ProgressBar默认这个属性设置为true),对于水平ProgressBar的话,如果设置为true,则出现一个默认的加载的动画,即android:indeterminateDrawable中设置的

progress_indeterminate_horizonta.xml:

<?xml version="1.0" encoding="utf-8"?>
<animation-list
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:oneshot="false">
    <item android:drawable="@drawable/progressbar_indeterminate1" android:duration="200" />
    <item android:drawable="@drawable/progressbar_indeterminate2" android:duration="200" />
    <item android:drawable="@drawable/progressbar_indeterminate3" android:duration="200" />
</animation-list>

这里面就是 3张这样的图片,在循环播放:

 

在布局文件中设置:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    tools:context=".MainActivity"
    android:background="#ffffff" >
    
    <!-- 圆形的progressBar -->
    <ProgressBar
        android:id="@+id/pb_circle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dip"
        android:layout_centerHorizontal="true"
        />

    <!-- 水平的progressBar  android:indeterminateOnly="true"-->
    <ProgressBar
        android:id="@+id/pb_horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_below="@+id/pb_circle"
        android:layout_marginTop="30dip"
        style="?android:attr/progressBarStyleHorizontal"
        android:progress="50"
        android:secondaryProgress="60"
        android:minWidth="200dip"
        android:indeterminateOnly="true"
        />
    
</RelativeLayout>

  效果如下:

 

 上面的水平ProgressBar中还设置了android:progress="50"和android:secondaryProgress="60"这两个属性,但是不起作用。这是因为我们设置了android:indeterminateOnly="true"

这个时候我们通常会想到在java代码中去将这个值设置为false,然后再设置进度progress,可是我并没有发现有这样的方法,查阅了sdk文档也没有发现,后来发现了有人利用了反射可已将源码中的mOnlyIndeterminate字段设置为false,这就达到了我们的目的了:

 

BeanUtils.java:

public class BeanUtils {   
    private BeanUtils() {   
  
    }   
  
    /**  
     * 直接设置对象属性值,无视private/protected修饰符,不经过setter函数.  
     */  
    public static void setFieldValue(final Object object, final String fieldName, final Object value) {   
        Field field = getDeclaredField(object, fieldName);   
        if (field == null)   
            throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]");   
        makeAccessible(field);   
        try {   
            field.set(object, value);   
        } catch (IllegalAccessException e) {   
        Log.e("got exception:", "", e);   
        }   
    }   
  
    /**  
     * 循环向上转型,获取对象的DeclaredField.  
     */  
    protected static Field getDeclaredField(final Object object, final String fieldName) {   
        return getDeclaredField(object.getClass(), fieldName);   
    }   
  
    /**  
     * 循环向上转型,获取类的DeclaredField.  
     */  
    @SuppressWarnings("unchecked")   
    protected static Field getDeclaredField(final Class clazz, final String fieldName) {   
        for (Class superClass = clazz; superClass != Object.class; superClass = superClass.getSuperclass()) {   
            try {   
                return superClass.getDeclaredField(fieldName);   
            } catch (NoSuchFieldException e) {   
                // Field不在当前类定义,继续向上转型   
            }   
        }   
        return null;   
    }   
  
    /**  
     * 强制转换fileld可访问.  
     */  
    protected static void makeAccessible(Field field) {   
        if (!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers())) {   
            field.setAccessible(true);   
        }   
    }

}  

 

 MainActivity.java:

Timer timer = new Timer();
		timer.schedule(new TimerTask()
		{

			@Override
			public void run() 
			{
				//执行的内容
				
				BeanUtils.setFieldValue((Object)pbHorizontal, "mOnlyIndeterminate", (Object)Boolean.valueOf(false));
				pbHorizontal.setIndeterminate(false);  
				pbHorizontal.setProgress(50);
				pbHorizontal.setSecondaryProgress(60);
			}
			
		}, 3000);//表示3秒后执行

 效果如下:

 

 

这样我们就可以实现:在正在加载数据之前显示默认的动画,而在加载数据的时候显示具体的进度。

 

 

 还是存在这样一个大问题,那就是默认的ProgressBar的样式实在不敢恭维,当然通过上面的分析,我们可以很容易地对默认的style进行覆盖。

1.自定义小菊花进度条:

 

通过Widget.ProgressBar中的style的<item name="android:indeterminateDrawable">@android:drawable/progress_medium_white</item>我们去源码中查找:

 progress_medium_white.xml:

<?xml version="1.0" encoding="utf-8"?>
<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/spinner_white_48"
    android:pivotX="50%"
    android:pivotY="50%"
    android:framesCount="12"
    android:frameDuration="100" />

 发现spinner_white_48是一张图片:

 

这就很简单了,我们可以替换掉style中默认的android:indeterminateDrawable为自己的drawable就可以了:

1.在res/drawable/indicate.xml:

 

<?xml version="1.0" encoding="utf-8"?>
<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/indeterminate_progress_1"
    android:pivotX="50%"
    android:pivotY="50%"
     />

 indeterminate_progress_1就是我们自定义的小菊花图片了

 

 2.然后在布局文件中:

 

<!-- 圆形的progressBar -->
    <ProgressBar
        android:id="@+id/pb_circle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dip"
        android:layout_centerHorizontal="true"
        android:indeterminateDrawable="@drawable/indicate"
        />

 就这么简单,看了很多人的博客,有的人采用的是10几张图片通过Progressbar进行播放,有的采用一个ImageView对10几张图片进行重复播放或者对一张图片进行旋转,我认为我的这种方式比较好,比较方便,而且只要一张图就够了。

 

 

 

2.自定义水平的ProgressBar:

我们要改变的是Widget.ProgressBar.Horizontal中的drawable/progress_horizontal和drawable/progress_indeterminate_horizontal

drawable/progress_horizontal.xml:

<?xml version="1.0" encoding="utf-8"?>
<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="270"
            />
        </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="270"
                />
            </shape>
        </clip>
    </item>
    
    <item android:id="@android:id/progress">
        <clip>
            <shape>
                <corners android:radius="5dip" />
                <gradient
                        android:startColor="#ffffd300"
                        android:centerColor="#ffffb600"
                        android:centerY="0.75"
                        android:endColor="#ffffcb00"
                        android:angle="270"
                />
            </shape>
        </clip>
    </item>
    
</layer-list>

 这实际上是通过xml来绘制图片,当然你可以以类似的方式来实现自己的效果。

 

progress_indeterminate_horizontal.xml:(这个在前面已经介绍过了)

<?xml version="1.0" encoding="utf-8"?>
<animation-list
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:oneshot="false">
    <item android:drawable="@drawable/progressbar_indeterminate1" android:duration="200" />
    <item android:drawable="@drawable/progressbar_indeterminate2" android:duration="200" />
    <item android:drawable="@drawable/progressbar_indeterminate3" android:duration="200" />
</animation-list>

 

 

为了图方便,我直接到4.0的源码中,找到这个文件直接拿出来用,这样你就可以在4.0及以下的系统中看到4.0ProgressBar的效果了:

1.布局文件中:

<ProgressBar
        android:id="@+id/pb_horizontal"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="50dip"
        android:layout_marginRight="50dip"
        android:layout_centerHorizontal="true"
        android:layout_below="@+id/pb_circle"
        android:layout_marginTop="30dip"
        style="?android:attr/progressBarStyleHorizontal"
        android:progressDrawable="@drawable/pb_layer_list"
        android:indeterminateDrawable="@drawable/bg_progressbar"
        android:indeterminateOnly="true"
        />

 

2.res/drawable/pb_layout_list.xml:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:id="@android:id/background"
          android:drawable="@drawable/progress_bg_holo_dark" />

    <item android:id="@android:id/secondaryProgress">
        <scale android:scaleWidth="100%"
               android:drawable="@drawable/progress_secondary_holo_dark" />
    </item>

    <item android:id="@android:id/progress">
        <scale android:scaleWidth="100%"
               android:drawable="@drawable/progress_primary_holo_dark" />
    </item>

</layer-list>

 

 

3.res/drawable/bg_progressbar.xml:

<?xml version="1.0" encoding="utf-8"?>
<animation-list
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:oneshot="false">
    <item android:drawable="@drawable/progressbar_indeterminate_holo1" android:duration="200" />
    <item android:drawable="@drawable/progressbar_indeterminate_holo2" android:duration="200" />
    <item android:drawable="@drawable/progressbar_indeterminate_holo3" android:duration="200" />
    <item android:drawable="@drawable/progressbar_indeterminate_holo4" android:duration="200" />
    <item android:drawable="@drawable/progressbar_indeterminate_holo5" android:duration="200" />
    <item android:drawable="@drawable/progressbar_indeterminate_holo6" android:duration="200" />
    <item android:drawable="@drawable/progressbar_indeterminate_holo7" android:duration="200" />
    <item android:drawable="@drawable/progressbar_indeterminate_holo8" android:duration="200" />
</animation-list>

 

相应的图片文件你都可以在源码中找到。下面我们看看自定义后的运行效果:

 

 

 信息量有点大,希望大家能够看的懂,如果自己能够去尝试一下,应该能够更好地了解。

主要的实现步骤在上面都以红颜色表示出来了。

 

 

 

 

 

 

 

  • 大小: 63.3 KB
  • 大小: 3.6 KB
  • 大小: 67.9 KB
  • 大小: 4 KB
  • 大小: 93.3 KB
1
0
分享到:
评论

相关推荐

    带动画的横向ProgressBar

    在Android开发中,ProgressBar是用户界面中非常常见的一种组件,用于表示某个操作的进度或等待状态。本主题聚焦于“带动画的横向ProgressBar”,这种组件能够以动态的方式展示进度变化,提升用户体验。以下是对这个...

    Android 自定义各式各样的圆形ProgressBar

    在Android开发中,ProgressBar是用户界面(UI)设计中一个重要的元素,用于向用户展示某个操作的进度或者等待状态。通常,系统提供的ProgressBar样式有限,但开发者可以通过自定义来实现更多样化的效果,以满足不同...

    Progressbar进度条的使用

    在Android开发中,`ProgressBar`是一个非常常见的组件,它用于展示任务执行的进度,比如文件下载、上传或者网络请求等。本教程将深入探讨如何利用`Handler`消息机制来实现`ProgressBar`的动态更新,展示进度条中进度...

    c# ProgressBar 光滑进度条 源码

    在C#编程中,ProgressBar控件是用于向用户显示任务进度的一个重要元素。"Smooth ProgressBar"则是一种增强型的进度条,它提供了平滑、连续的动画效果,使得用户界面更具吸引力和反馈感。在Windows Forms或WPF应用中...

    页面上现有ProgressBar控件progressBar,请用书写线程以10秒的的时间完成其进度显示工作

    在Windows Forms或WPF应用程序中,`ProgressBar`控件是一个常用元素,用于向用户展示某个操作的进度。在这个场景中,我们需要使用线程技术来控制`ProgressBar`在10秒内逐渐填充,以模拟一个耗时操作的进度。下面将...

    超级漂亮的 progressbar效果

    【ProgressBar】既进度条,当我们在做一些耗时操作的时候(例如下载文件),可以使用ProgressBar给用户提供一个进度提示,告诉用户当前的进度。 ProgressBar.js 是一个借助动态 SVG 路径的漂亮的,响应式的进度条...

    Android应用源码之ProgressBar 几乎全部的用法

    在Android开发中,ProgressBar是一个非常重要的组件,它用于显示进度或等待状态,为用户提供反馈,表明应用程序正在进行后台处理。ProgressBar提供了多种样式和用法,包括水平、垂直、圆形以及自定义样式。本教程将...

    winform c# ProgressBar特殊样式style

    在Windows Forms(Winform)开发中,`ProgressBar`控件常用于显示任务进度或等待状态。然而,系统默认的`ProgressBar`样式较为简单,可能无法满足开发者对于界面美观度的需求。`winform c# ProgressBar特殊样式style...

    C# progressBar进度条绘制文字显示百分比

    在C#编程中,`progressBar`控件是Windows Forms应用程序中常见的元素,用于向用户显示操作的进度。默认情况下,进度条仅通过其填充部分的长度来表示进度,但有时候我们希望更直观地显示进度,例如以百分比的形式。本...

    WPF实现ProgressBar气泡显示进度值

    在Windows Presentation Foundation (WPF) 中,ProgressBar 是一个常见的控件,用于显示应用程序执行过程中的进度。本项目“WPF实现ProgressBar气泡显示进度值”着重于改进此控件,使其能够以更直观的方式呈现进度...

    WPF,好看的圆形ProgressBar实现

    在Windows Presentation Foundation (WPF) 中,ProgressBar 是一个非常有用的控件,用于显示进度或操作完成的百分比。当我们想要创建一个美观且引人注目的界面时,圆形ProgressBar(也称为环形进度条)是一个很好的...

    自定义ProgressBar的菊花加载

    在Android开发中,ProgressBar是用于显示进度或加载状态的一个组件,它可以帮助用户了解应用程序后台运行的任务正在处理中。本主题将深入探讨如何自定义ProgressBar,特别是实现“菊花加载”效果,这种效果通常在...

    WPF中使用ProgressBar实现垂直温度计效果

    在Windows Presentation Foundation (WPF) 中,ProgressBar是一个用于显示进度的可视化控件,通常用于表示一个操作的完成度。在本教程中,我们将探讨如何利用ProgressBar控件来创建一个垂直的温度计效果,以实现一个...

    ProgressBar的几个小样及自定义圆形ProgressBar半径大小 .

    ProgressBar是Android系统中一个常用的组件,它用于显示进度或加载状态。在Android开发中,我们经常需要自定义ProgressBar以满足不同界面设计的需求。本篇文章将深入探讨ProgressBar的几个常见样式以及如何自定义一...

    C# wpf中动态添加ProgressBar

    在C# WPF应用开发中,动态添加ProgressBar到ListView是一种常见的需求,特别是在处理大量数据或者进行后台任务执行时,为了提供用户友好的界面反馈。在VS(Visual Studio)开发环境中,我们可以利用WPF的灵活性和...

    Android下ProgressBar和旗下两个子控件的使用

    在Android开发中,ProgressBar是一个非常常见的控件,用于显示进度状态,可以是线性的或圆形的。本篇文章将深入探讨Android中的ProgressBar及其两个主要子类SeekBar和RatingBar的使用方法。 首先,我们来了解...

    C# Winform 自定义进度条ProgressBar

    "C# Winform 自定义进度条ProgressBar"的主题正聚焦于这一需求,允许开发者根据自己的喜好或者项目需求改变默认进度条的外观,特别是其背景颜色。 进度条(ProgressBar)是Windows应用程序中常见的一种组件,用于...

    C# winform 进度条 ProgressBar 带进度显示

    在C# Winform应用开发中,进度条控件(ProgressBar)是用户界面中不可或缺的一部分,它为用户提供关于长时间运行操作的进度反馈。本教程将详细讲解如何在Winform应用程序中创建一个带有进度显示的进度条。 首先,让...

    Android三种方式实现ProgressBar自定义圆形进度条

    进度条样式在项目中经常可以见到,下面小编给大家分享Android三种方式实现ProgressBar自定义圆形进度条。 Android进度条有4种风格可以使用。 默认值是progressBarStyle。 设置成progressBarStyleSmall后,图标变小...

Global site tag (gtag.js) - Google Analytics