AndroidUI组件之ProgressBar

本文详细介绍了Android中的ProgressBar组件,包括其常用属性、样式设定方法以及如何自定义进度条样式。此外,还探讨了如何通过代码控制进度条的显示效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package com.gc.progressbar;
/*
  * 1、ProgressBar组件也是一组重要的组件,ProgressBar本身代表了进度条组件,
  * 它还派生了两个常用的组件:SeekBar和RatingBar。
  * 2、进度条的功能与用法:
  * 进度条通常用于向用户显示某个耗时操作完成的百分比,进度条可以动态地显示进度
  * 因此避免长时间地执行某个耗时操作时,让用户感觉程序失去了响应。
  * Android支持如下几种风格的进度条,通过style属性可以为ProgressBar指定风格
  * @android:style/Widget.ProgressBar.Horizontal-----水平进度条
  * @android:style/Widget.ProgressBar.Inverse--------普通大小的环形进度条
  * @android:style/Widget.ProgressBar.Large----------大环形进度条
  * @android:style/Widget.ProgressBar.Large.Inverse---大环形进度条
  * @android:style/Widget.ProgressBar.Small-----------小环形进度条
  * @android:style/Widget.ProgressBar.Small.Inverse---小环形进度条
  * 3、ProgressBar常用的XML属性:
  * android:max-------------------设置该进度条的最大值
  * android:progress--------------设置该进度条的已完成进度值
  * android:progressDrawable------设置该进度条的轨道对应的Drawable对象
  * android:indeterminate---------该属性设为true,设置进度条不精确显示进度
  * android:indeterminateDrawable-设置绘制不显示进度的进度条的Drawable对象
  * android:indeterminateDuration-设置不精确显示进度的持续时间
  * android:progressDrawable用于指定进度条的轨道的绘制形式,该属性可指定为
  * 一个LayerDrawable对象(该对象可通过在XML文件中用<layer-list>元素进行配置 )的引用
  * 4、ProgressBar提供了下面两个方法来操作进度
  * setProgress(int) ---设置进度的完成百分比
  * incrementProgressBy(int)---设置进度条的进度增加或减少。当参数为正数时进度增加
  * ,当参数为负数时进度减少。
  */
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.view.Menu;
import android.widget.ProgressBar;
/**
  *
  * @author Android将军
  *
  */
public class MainActivity extends Activity {
     //该程序模拟填充长度为100的数组
     private int [] data= new int [ 100 ];
     private int hasData= 0 ;
     //记录ProgressBar的完成进度
     private int status= 0 ;
     private ProgressBar bar,bar2;
     //创建一个负责更新的进度的Handler
     Handler mHandler= new Handler()
     {
 
         @Override
         public void handleMessage(Message msg) {
             // TODO Auto-generated method stub
             //表明消息是由该程序发送的
             if (msg.what== 0x111 )
             {
                 bar.setProgress(status);
                 bar2.setProgress(status);
             }
         }
         
     };
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super .onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
         bar=(ProgressBar)findViewById(R.id.bar);
         bar2=(ProgressBar)findViewById(R.id.bar2);
         //启动线程来执行任务
         new Thread()
         {
             
             public void run()
             {
                 while (status< 100 )
                 {
                     //获取耗时操作的完成百分比
                     status=doWork();
                     //发送消息
                     mHandler.sendEmptyMessage( 0x111 );
                 }
             }
         }.start();
     }
 
     //模拟一个耗时的操作
     public int doWork() {
         // 为数组元素赋值
         data[hasData++]=( int )(Math.random()* 100 );
         try
         {
             Thread.sleep( 100 );
         } catch (InterruptedException e)
         {
             e.printStackTrace();
         }
         return hasData;
     }
 
 
}
</layer-list>
?
1
布局文件:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<linearlayout 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:orientation= "vertical" >
 
     <linearlayout android:orientation= "horizontal" android:layout_width= "match_parent" android:layout_height= "wrap_content" >
         <!-- 定义一个大环形进度条 -->
         <progressbar android:layout_width= "wrap_content" android:layout_height= "wrap_content" style= "@android:style/Widget.ProgressBar.Large" >
         <!-- 定义一个中等大小的环形进度条 -->
         <progressbar android:layout_width= "wrap_content" android:layout_height= "wrap_content" >
         <!-- 定义一个小环形进度条 -->
         <progressbar android:layout_width= "wrap_content" android:layout_height= "wrap_content" style= "@android:style/Widget.ProgressBar.Small" >
     </progressbar></progressbar></progressbar></linearlayout>
     <textview android:layout_width= "fill_parent" android:layout_height= "wrap_content" android:text= "任务完成的进度" >
     <!-- 定义一个水平进度条 -->
     <progressbar android:id= "@+id/bar" android:layout_width= "fill_parent" android:layout_height= "wrap_content" android:max= "100" style= "@android:style/Widget.ProgressBar.Horizontal" >
     <!-- 定义一个水平进度条,并改变轨道外观 -->
     <progressbar android:id= "@+id/bar2" android:layout_width= "fill_parent" android:layout_height= "wrap_content" android:max= "100" android:progressdrawable= "@drawable/my_bar" style= "@android:style/Widget.ProgressBar.Horizontal" >
 
</progressbar></progressbar></textview></linearlayout>

转载请注明出处:http://blog.youkuaiyun.com/android_jiangjun/article/details/2555563


ProgressBar简介


继承于View类,直接子类有AbsSeekBar和ContentLoadingProgressBar,其中AbsSeekBar的子类有SeekBar和RatingBar,可见这二者也是基于ProgressBar实现的。


1、ProgressBar有两个进度,一个是android:progress,另一个是android:secondaryProgress。后者主要是为缓存需要所涉及的,比如在看网络视频时候都会有一个缓存的进度条以及还要一个播放的进度,在这里缓存的进度就可以是android:secondaryProgress,而播放进度就是android:progress,有了secondProgress,可以很方便定制ProgressBar。

 2、ProgressBar分为确定的和不确定的,确定的是我们能明确看到进度,相反不确定的就是不清楚、不确定一个操作需要多长时间来完成,这个时候就需要用的不确定的ProgressBar了。属性android:indeterminate如果设置为true的话,那么ProgressBar就可能是圆形的滚动条或者水平的滚动条(由样式决定),但是我们一般时候,是直接使用Style类型来区分圆形还是水平ProgressBar的。

3、ProgressBar的样式设定其实有两种方式,在API文档中说明的方式如下:

  • Widget.ProgressBar.Horizontal
  • Widget.ProgressBar.Small
  • Widget.ProgressBar.Large
  • Widget.ProgressBar.Inverse
  • Widget.ProgressBar.Small.Inverse
  • Widget.ProgressBar.Large.Inverse
   使用的时候可以这样:style="@android:style/Widget.ProgressBar.Small",另外还有一种方式就是使用系统的attr,下面的方式是系统的style:

  • style="?android:attr/progressBarStyle" 
  • style="?android:attr/progressBarStyleHorizontal" 
  • style="?android:attr/progressBarStyleInverse" 
  • style="?android:attr/progressBarStyleLarge" 
  • style="?android:attr/progressBarStyleLargeInverse" 
  • style="?android:attr/progressBarStyleSmall" 
  • style="?android:attr/progressBarStyleSmallInverse" 
  • style="?android:attr/progressBarStyleSmallTitle" 
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <ProgressBar  
  2.      android:id="@+id/progressBar1"  
  3.      style="?android:attr/progressBarStyleHorizontal"  
  4.      style="@android:style/Widget.ProgressBar.Horizontal"(等同于@android:attr)  
  5.      android:layout_width="match_parent"  
  6.      android:layout_height="wrap_content" />  

水平ProgressBar系统样式

我们去看一下style="?android:attr/progressBarStyleHorizontal"的源码,如下:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <pre name="code" class="java">    <style name="Widget.ProgressBar.Horizontal">  
  2.         <item name="android:indeterminateOnly">false</item>  
  3.         <item name="android:progressDrawable">@android:drawable/progress_horizontal</item>  
  4.         <item name="android:indeterminateDrawable">@android:drawable/progress_indeterminate_horizontal</item>  
  5.         <item name="android:minHeight">20dip</item>  
  6.         <item name="android:maxHeight">20dip</item>  
  7.         <item name="android:mirrorForRtl">true</item>  
  8.     </style>  
 
一眼看出
android:progressDrawable
便是主角,继续看一下progress_horizontal的源码,如下: 

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <!-- Copyright (C) 2008 The Android Open Source Project  
  3.   
  4.      Licensed under the Apache License, Version 2.0 (the "License");  
  5.      you may not use this file except in compliance with the License.  
  6.      You may obtain a copy of the License at  
  7.   
  8.           http://www.apache.org/licenses/LICENSE-2.0  
  9.   
  10.      Unless required by applicable law or agreed to in writing, software  
  11.      distributed under the License is distributed on an "AS IS" BASIS,  
  12.      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  
  13.      See the License for the specific language governing permissions and  
  14.      limitations under the License.  
  15. -->  
  16.   
  17. <layer-list xmlns:android="http://schemas.android.com/apk/res/android">  
  18.      
  19.     <item android:id="@android:id/background">  
  20.         <shape>  
  21.             <corners android:radius="5dip" />  
  22.             <gradient  
  23.                     android:startColor="#ff9d9e9d"  
  24.                     android:centerColor="#ff5a5d5a"  
  25.                     android:centerY="0.75"  
  26.                     android:endColor="#ff747674"  
  27.                     android:angle="270"  
  28.             />  
  29.         </shape>  
  30.     </item>  
  31.      
  32.     <item android:id="@android:id/secondaryProgress">  
  33.         <clip>  
  34.             <shape>  
  35.                 <corners android:radius="5dip" />  
  36.                 <gradient  
  37.                         android:startColor="#80ffd300"  
  38.                         android:centerColor="#80ffb600"  
  39.                         android:centerY="0.75"  
  40.                         android:endColor="#a0ffcb00"  
  41.                         android:angle="270"  
  42.                 />  
  43.             </shape>  
  44.         </clip>  
  45.     </item>  
  46.      
  47.     <item android:id="@android:id/progress">  
  48.         <clip>  
  49.             <shape>  
  50.                 <corners android:radius="5dip" />  
  51.                 <gradient  
  52.                         android:startColor="#ffffd300"  
  53.                         android:centerColor="#ffffb600"  
  54.                         android:centerY="0.75"  
  55.                         android:endColor="#ffffcb00"  
  56.                         android:angle="270"  
  57.                 />  
  58.             </shape>  
  59.         </clip>  
  60.     </item>  
  61.      
  62. </layer-list>  

这里面有3个item,分别为:background、secondProgress、progress,看名字就能知道其大概作用,我们比较关心的应该是后两个,其实把这个文件copy一份到自己的项目下,就可以随心所欲的修改shape属性:圆角、渐变等等。

自定义水平ProgressBar

第一步,在drawable文件夹下新建一个progressbar_horizontal_1.xml:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <layer-list xmlns:android="http://schemas.android.com/apk/res/android" >  
  3.   
  4.     <!-- background -->  
  5.     <item  
  6.         android:id="@android:id/background"  
  7.         android:drawable="@drawable/progress_patch_green">  
  8.     </item>  
  9.     <!-- progress -->  
  10.     <item android:id="@android:id/progress">  
  11.         <clip>  
  12.             <nine-patch android:src="@drawable/progress_patch_galy" />  
  13.         </clip>  
  14.     </item>  
  15.     <!-- second progress -->  
  16.   
  17.     <item android:id="@android:id/secondaryProgress">  
  18.         <clip>  
  19.             <nine-patch android:src="@drawable/progresspatch_blue" />  
  20.         </clip>  
  21.     </item>  
  22.   
  23. </layer-list>  

上图中的progress和secondprogress中src的资源便是我自定义的,注意这三个之间的叠放顺序,background是最底层,中间的是progress最上层是second。

第二步,标准一点,在style中新建我们自定义的style:mProgress_horizontal:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <style name="mProgress_horizontal">  
  2.     <item name="android:indeterminateOnly">false</item>  
  3.     <item name="android:progressDrawable">@drawable/progressbar_horizontal_1</item><!-- progress_horizontal -->  
  4.     <item name="android:indeterminateDrawable">@android:drawable/progress_indeterminate_horizontal</item>  
  5.     <item name="android:minHeight">20dip</item>  
  6.     <item name="android:maxHeight">20dip</item>  
  7. </style>  

上图中prpgressDrawable资源便是指向了我们自定义的progressbar_horizontal_1,大功告成。

第三步,组件引用:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <ProgressBar  
  2.     android:id="@+id/progressBar1"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="wrap_content"  
  5.     android:background="@drawable/progress_backround"  
  6.     android:padding="5dp"  
  7.     android:progress="50"  
  8.     style="@style/mProgress_horizontal"  
  9.     android:secondaryProgress="20"  
  10.     android:visibility="visible" />  

【附】

在这里我们也可以省略第二步创建style,直接在组件中android:progressDrawable引用自己的progressbar_horizontal_1,如下:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <ProgressBar  
  2.     android:id="@+id/progressBar1"  
  3.     android:indeterminate="false"  
  4.     android:indeterminateOnly="false"  
  5.     android:layout_width="match_parent"  
  6.     android:layout_height="wrap_content"  
  7.     android:background="@drawable/progress_backround"  
  8.     android:padding="5dp"  
  9.     android:progress="50"  
  10.     android:maxHeight="20dp"  
  11.     android:minHeight="20dp"  
  12.     android:progressDrawable="@drawable/progressbar_horizontal_1"  
  13.     android:secondaryProgress="20"  
  14.     />  

第四步,效果图:

圆形ProgressBar系统样式

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <ProgressBar  
  2.     android:id="@+id/progressBar2"  
  3.     style="@android:attr/progressBarStyleLarge"  
  4.     android:layout_gravity="center_vertical"  
  5.     android:layout_width="match_parent"  
  6.     android:layout_height="wrap_content" />  

我们以progressBarStyleLarge为例进行探索,找到这个布局文件,源码如下:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <style name="Widget.ProgressBar.Large">  
  2.   <item name="android:indeterminateDrawable">@android:drawable/progress_large_white</item>  
  3.   <item name="android:minWidth">76dip</item>  
  4.   <item name="android:maxWidth">76dip</item>  
  5.   <item name="android:minHeight">76dip</item>  
  6.   <item name="android:maxHeight">76dip</item>  
  7. </style>  

同样一眼看出 indeterminateDrawable 便是主角了,继续看一下progress_large_white源码,如下:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <rotate xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     android:drawable="@drawable/spinner_white_76"  
  3.     android:pivotX="50%"  
  4.     android:pivotY="50%"  
  5.     android:fromDegrees="0"  
  6.     android:toDegrees="360" />  

看到这里就透彻了,就是在这里spinner_white_76进行不停的旋转的,我们copy一下这个文件,就可以直接自定义了。

自定义圆形ProgressBar

第一步,在drawable文件夹下新建:progressbar_circle_1.xml,如下:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <rotate xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:drawable="@drawable/loading" //自定义的菊花图片  
  4.     android:fromDegrees="0"  
  5.     android:pivotX="50%"  
  6.     android:pivotY="50%"  
  7.     android:toDegrees="360" >  
  8.   
  9. </rotate>  

第二步,在Style中定义mProgress_circle,如下:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <style name="mProgress_circle">  
  2.     <item name="android:indeterminateDrawable">@drawable/progressbar_circle_1</item>  
  3.     <item name="android:minWidth">25dp</item>  
  4.     <item name="android:minHeight">25dp</item>  
  5.     <item name="android:maxWidth">60dp</item>  
  6.     <item name="android:maxHeight">60dp</item>  
  7. </style>  

支持大小自己随意定,别失真就好

第三步,组件中引用,如下:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <ProgressBar  
  2.     android:id="@+id/progressBar2"  
  3.     style="@style/mProgress_circle"  
  4.     android:layout_gravity="center_vertical"  
  5.     android:layout_width="match_parent"  
  6.     android:indeterminateDuration="1200"  
  7.     android:layout_height="wrap_content" />  

【附】
上面是通过一张图片填充 android:indeterminateDrawable ,我们也可以定义一个 动画 或者自定义 颜色(shape) 来实现,跟图片的用法一样:

定义动画 progress_circle_loading,xml:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="UTF-8"?>    
  2. <animation-list android:oneshot="false"    
  3.   xmlns:android="http://schemas.android.com/apk/res/android">    
  4.   <item android:duration="100" android:drawable="@drawable/loading_1" />    
  5.   <item android:duration="100" android:drawable="@drawable/loading_2" />    
  6.   <item android:duration="100" android:drawable="@drawable/loading_3" />    
  7.   <item android:duration="100" android:drawable="@drawable/loading_4" />    
  8.   <item android:duration="100" android:drawable="@drawable/loading_5" />    
  9.   <item android:duration="100" android:drawable="@drawable/loading_6" />  
  10. </animation-list>  

style的indeterminateDrawable引入:
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <pre name="code" class="java"><item name="android:indeterminateDrawable">@drawable/progress_circle_loading</item>  
 

定义shape颜色 progress_circle_shape.xml

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>    
  2. <rotate xmlns:android="http://schemas.android.com/apk/res/android"    
  3.   android:fromDegrees="0"    
  4.   android:pivotX="50%"    
  5.   android:pivotY="50%"    
  6.   android:toDegrees="360" >    
  7.   <shape    
  8.     android:innerRadiusRatio="3"    
  9.     android:shape="ring"    
  10.     android:thicknessRatio="8"    
  11.     android:useLevel="false" >    
  12.     <gradient    
  13.       android:centerColor="#FFFFFF"    
  14.       android:centerY="0.50"    
  15.       android:endColor="#1E90FF"    
  16.       android:startColor="#000000"    
  17.       android:type="sweep"    
  18.       android:useLevel="false" />    
  19.   </shape>    
  20. </rotate>  


style的indeterminateDrawable引入:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <item name="android:indeterminateDrawable">@drawable/progress_circle_shape</item>  


效果图如下:





SeekBar的原理是一样的,不信你看下图,我就是用的seekbar


最后来张全家福:




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

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

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

Java代码   收藏代码
  1. style="?android:attr/progressBarStyleHorizontal"  

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

 

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

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

Java代码   收藏代码
  1. <style   
  2.         name="test" parent="@android:style/Widget.ProgressBar">  
  3. </style>  

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

 

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

 

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

Java代码   收藏代码
  1. <style name="Widget.ProgressBar">  
  2.         <item name="android:indeterminateOnly">true</item>  
  3.         <item name="android:indeterminateDrawable">@android:drawable/progress_medium_white</item>  
  4.         <item name="android:indeterminateBehavior">repeat</item>  
  5.         <item name="android:indeterminateDuration">3500</item>  
  6.         <item name="android:minWidth">48dip</item>  
  7.         <item name="android:maxWidth">48dip</item>  
  8.         <item name="android:minHeight">48dip</item>  
  9.         <item name="android:maxHeight">48dip</item>  
  10.     </style>  
  11.   
  12. <style name="Widget.ProgressBar.Horizontal">  
  13.         <item name="android:indeterminateOnly">false</item>  
  14.         <item name="android:progressDrawable">@android:drawable/progress_horizontal</item>  
  15.         <item name="android:indeterminateDrawable">@android:drawable/progress_indeterminate_horizontal</item>  
  16.         <item name="android:minHeight">20dip</item>  
  17.         <item name="android:maxHeight">20dip</item>  
  18.     </style>  

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

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

progress_indeterminate_horizonta.xml:

Java代码   收藏代码
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <animation-list  
  3.         xmlns:android="http://schemas.android.com/apk/res/android"  
  4.         android:oneshot="false">  
  5.     <item android:drawable="@drawable/progressbar_indeterminate1" android:duration="200" />  
  6.     <item android:drawable="@drawable/progressbar_indeterminate2" android:duration="200" />  
  7.     <item android:drawable="@drawable/progressbar_indeterminate3" android:duration="200" />  
  8. </animation-list>  

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

 

在布局文件中设置:

Java代码   收藏代码
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent"  
  5.     tools:context=".MainActivity"  
  6.     android:background="#ffffff" >  
  7.       
  8.     <!-- 圆形的progressBar -->  
  9.     <ProgressBar  
  10.         android:id="@+id/pb_circle"  
  11.         android:layout_width="wrap_content"  
  12.         android:layout_height="wrap_content"  
  13.         android:layout_marginTop="30dip"  
  14.         android:layout_centerHorizontal="true"  
  15.         />  
  16.   
  17.     <!-- 水平的progressBar  android:indeterminateOnly="true"-->  
  18.     <ProgressBar  
  19.         android:id="@+id/pb_horizontal"  
  20.         android:layout_width="wrap_content"  
  21.         android:layout_height="wrap_content"  
  22.         android:layout_centerHorizontal="true"  
  23.         android:layout_below="@+id/pb_circle"  
  24.         android:layout_marginTop="30dip"  
  25.         style="?android:attr/progressBarStyleHorizontal"  
  26.         android:progress="50"  
  27.         android:secondaryProgress="60"  
  28.         android:minWidth="200dip"  
  29.         android:indeterminateOnly="true"  
  30.         />  
  31.       
  32. </RelativeLayout>  

  效果如下:

 

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

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

 

BeanUtils.java:

Java代码   收藏代码
  1. public class BeanUtils {     
  2.     private BeanUtils() {     
  3.     
  4.     }     
  5.     
  6.     /**   
  7.      * 直接设置对象属性值,无视private/protected修饰符,不经过setter函数.   
  8.      */    
  9.     public static void setFieldValue(final Object object, final String fieldName, final Object value) {     
  10.         Field field = getDeclaredField(object, fieldName);     
  11.         if (field == null)     
  12.             throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]");     
  13.         makeAccessible(field);     
  14.         try {     
  15.             field.set(object, value);     
  16.         } catch (IllegalAccessException e) {     
  17.         Log.e("got exception:""", e);     
  18.         }     
  19.     }     
  20.     
  21.     /**   
  22.      * 循环向上转型,获取对象的DeclaredField.   
  23.      */    
  24.     protected static Field getDeclaredField(final Object object, final String fieldName) {     
  25.         return getDeclaredField(object.getClass(), fieldName);     
  26.     }     
  27.     
  28.     /**   
  29.      * 循环向上转型,获取类的DeclaredField.   
  30.      */    
  31.     @SuppressWarnings("unchecked")     
  32.     protected static Field getDeclaredField(final Class clazz, final String fieldName) {     
  33.         for (Class superClass = clazz; superClass != Object.class; superClass = superClass.getSuperclass()) {     
  34.             try {     
  35.                 return superClass.getDeclaredField(fieldName);     
  36.             } catch (NoSuchFieldException e) {     
  37.                 // Field不在当前类定义,继续向上转型     
  38.             }     
  39.         }     
  40.         return null;     
  41.     }     
  42.     
  43.     /**   
  44.      * 强制转换fileld可访问.   
  45.      */    
  46.     protected static void makeAccessible(Field field) {     
  47.         if (!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers())) {     
  48.             field.setAccessible(true);     
  49.         }     
  50.     }  
  51.   
  52. }    

 

 MainActivity.java:

Java代码   收藏代码
  1. Timer timer = new Timer();  
  2.         timer.schedule(new TimerTask()  
  3.         {  
  4.   
  5.             @Override  
  6.             public void run()   
  7.             {  
  8.                 //执行的内容  
  9.                   
  10.                 BeanUtils.setFieldValue((Object)pbHorizontal, "mOnlyIndeterminate", (Object)Boolean.valueOf(false));  
  11.                 pbHorizontal.setIndeterminate(false);    
  12.                 pbHorizontal.setProgress(50);  
  13.                 pbHorizontal.setSecondaryProgress(60);  
  14.             }  
  15.               
  16.         }, 3000);//表示3秒后执行  

 效果如下:

 

 

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

 

 

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

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

 

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

 progress_medium_white.xml:

Java代码   收藏代码
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:drawable="@drawable/spinner_white_48"  
  4.     android:pivotX="50%"  
  5.     android:pivotY="50%"  
  6.     android:framesCount="12"  
  7.     android:frameDuration="100" />  

 发现spinner_white_48是一张图片:

 

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

1.在res/drawable/indicate.xml:

 

Java代码   收藏代码
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:drawable="@drawable/indeterminate_progress_1"  
  4.     android:pivotX="50%"  
  5.     android:pivotY="50%"  
  6.      />  

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

 

 2.然后在布局文件中:

 

Java代码   收藏代码
  1. <!-- 圆形的progressBar -->  
  2.     <ProgressBar  
  3.         android:id="@+id/pb_circle"  
  4.         android:layout_width="wrap_content"  
  5.         android:layout_height="wrap_content"  
  6.         android:layout_marginTop="30dip"  
  7.         android:layout_centerHorizontal="true"  
  8.         android:indeterminateDrawable="@drawable/indicate"  
  9.         />  

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

 

 

 

2.自定义水平的ProgressBar:

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

drawable/progress_horizontal.xml:

Java代码   收藏代码
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <layer-list xmlns:android="http://schemas.android.com/apk/res/android">  
  3.       
  4.     <item android:id="@android:id/background">  
  5.         <shape>  
  6.             <corners android:radius="5dip" />  
  7.             <gradient  
  8.                     android:startColor="#ff9d9e9d"  
  9.                     android:centerColor="#ff5a5d5a"  
  10.                     android:centerY="0.75"  
  11.                     android:endColor="#ff747674"  
  12.                     android:angle="270"  
  13.             />  
  14.         </shape>  
  15.     </item>  
  16.       
  17.     <item android:id="@android:id/secondaryProgress">  
  18.         <clip>  
  19.             <shape>  
  20.                 <corners android:radius="5dip" />  
  21.                 <gradient  
  22.                         android:startColor="#80ffd300"  
  23.                         android:centerColor="#80ffb600"  
  24.                         android:centerY="0.75"  
  25.                         android:endColor="#a0ffcb00"  
  26.                         android:angle="270"  
  27.                 />  
  28.             </shape>  
  29.         </clip>  
  30.     </item>  
  31.       
  32.     <item android:id="@android:id/progress">  
  33.         <clip>  
  34.             <shape>  
  35.                 <corners android:radius="5dip" />  
  36.                 <gradient  
  37.                         android:startColor="#ffffd300"  
  38.                         android:centerColor="#ffffb600"  
  39.                         android:centerY="0.75"  
  40.                         android:endColor="#ffffcb00"  
  41.                         android:angle="270"  
  42.                 />  
  43.             </shape>  
  44.         </clip>  
  45.     </item>  
  46.       
  47. </layer-list>  

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

 

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

Java代码   收藏代码
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <animation-list  
  3.         xmlns:android="http://schemas.android.com/apk/res/android"  
  4.         android:oneshot="false">  
  5.     <item android:drawable="@drawable/progressbar_indeterminate1" android:duration="200" />  
  6.     <item android:drawable="@drawable/progressbar_indeterminate2" android:duration="200" />  
  7.     <item android:drawable="@drawable/progressbar_indeterminate3" android:duration="200" />  
  8. </animation-list>  

 

 

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

1.布局文件中:

Java代码   收藏代码
  1. <ProgressBar  
  2.         android:id="@+id/pb_horizontal"  
  3.         android:layout_width="fill_parent"  
  4.         android:layout_height="wrap_content"  
  5.         android:layout_marginLeft="50dip"  
  6.         android:layout_marginRight="50dip"  
  7.         android:layout_centerHorizontal="true"  
  8.         android:layout_below="@+id/pb_circle"  
  9.         android:layout_marginTop="30dip"  
  10.         style="?android:attr/progressBarStyleHorizontal"  
  11.         android:progressDrawable="@drawable/pb_layer_list"  
  12.         android:indeterminateDrawable="@drawable/bg_progressbar"  
  13.         android:indeterminateOnly="true"  
  14.         />  

 

2.res/drawable/pb_layout_list.xml:

Java代码   收藏代码
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <layer-list xmlns:android="http://schemas.android.com/apk/res/android">  
  3.   
  4.     <item android:id="@android:id/background"  
  5.           android:drawable="@drawable/progress_bg_holo_dark" />  
  6.   
  7.     <item android:id="@android:id/secondaryProgress">  
  8.         <scale android:scaleWidth="100%"  
  9.                android:drawable="@drawable/progress_secondary_holo_dark" />  
  10.     </item>  
  11.   
  12.     <item android:id="@android:id/progress">  
  13.         <scale android:scaleWidth="100%"  
  14.                android:drawable="@drawable/progress_primary_holo_dark" />  
  15.     </item>  
  16.   
  17. </layer-list>  

 

 

3.res/drawable/bg_progressbar.xml:

Java代码   收藏代码
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <animation-list  
  3.         xmlns:android="http://schemas.android.com/apk/res/android"  
  4.         android:oneshot="false">  
  5.     <item android:drawable="@drawable/progressbar_indeterminate_holo1" android:duration="200" />  
  6.     <item android:drawable="@drawable/progressbar_indeterminate_holo2" android:duration="200" />  
  7.     <item android:drawable="@drawable/progressbar_indeterminate_holo3" android:duration="200" />  
  8.     <item android:drawable="@drawable/progressbar_indeterminate_holo4" android:duration="200" />  
  9.     <item android:drawable="@drawable/progressbar_indeterminate_holo5" android:duration="200" />  
  10.     <item android:drawable="@drawable/progressbar_indeterminate_holo6" android:duration="200" />  
  11.     <item android:drawable="@drawable/progressbar_indeterminate_holo7" android:duration="200" />  
  12.     <item android:drawable="@drawable/progressbar_indeterminate_holo8" android:duration="200" />  
  13. </animation-list>  

 

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

 

 

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

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

 

 

 

 

 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值