1. 程式人生 > >Android簡單自定義圓形和水平ProgressBar

Android簡單自定義圓形和水平ProgressBar

http://blog.csdn.net/mad1989/article/details/38042875

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" 
  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"的原始碼,如下:

  1. <prename="code"class="java"><stylename="Widget.ProgressBar.Horizontal">
  2.         <itemname="android:indeterminateOnly">false</item>
  3.         <itemname="android:progressDrawable">@android:drawable/progress_horizontal</item>
  4.         <itemname="android:indeterminateDrawable">@android:drawable/progress_indeterminate_horizontal</item>
  5.         <itemname="android:minHeight">20dip</item>
  6.         <itemname="android:maxHeight">20dip</item>
  7.         <itemname="android:mirrorForRtl">true</item>
  8.     </style>
一眼看出android:progressDrawable便是主角,繼續看一下progress_horizontal的原始碼,如下:
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <!-- Copyright (C) 2008 The Android Open Source Project  
  3.      Licensed under the Apache License, Version 2.0 (the "License");  
  4.      you may not use this file except in compliance with the License.  
  5.      You may obtain a copy of the License at  
  6.           http://www.apache.org/licenses/LICENSE-2.0
  7.      Unless required by applicable law or agreed to in writing, software  
  8.      distributed under the License is distributed on an "AS IS" BASIS,  
  9.      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  
  10.      See the License for the specific language governing permissions and  
  11.      limitations under the License.  
  12. -->  
  13. <layer-list xmlns:android="http://schemas.android.com/apk/res/android">  
  14.     <item android:id="@android:id/background">  
  15.         <shape>  
  16.             <corners android:radius="5dip" />  
  17.             <gradient  
  18.                     android:startColor="#ff9d9e9d"
  19.                     android:centerColor="#ff5a5d5a"
  20.                     android:centerY="0.75"
  21.                     android:endColor="#ff747674"
  22.                     android:angle="270"
  23.             />  
  24.         </shape>  
  25.     </item>  
  26.     <item android:id="@android:id/secondaryProgress">  
  27.         <clip>  
  28.             <shape>  
  29.                 <corners android:radius="5dip" />  
  30.                 <gradient  
  31.                         android:startColor="#80ffd300"
  32.                         android:centerColor="#80ffb600"
  33.                         android:centerY="0.75"
  34.                         android:endColor="#a0ffcb00"
  35.                         android:angle="270"
  36.                 />  
  37.             </shape>  
  38.         </clip>  
  39.     </item>  
  40.     <item android:id="@android:id/progress">  
  41.         <clip>  
  42.             <shape>  
  43.                 <corners android:radius="5dip" />  
  44.                 <gradient  
  45.                         android:startColor="#ffffd300"
  46.                         android:centerColor="#ffffb600"
  47.                         android:centerY="0.75"
  48.                         android:endColor="#ffffcb00"
  49.                         android:angle="270"
  50.                 />  
  51.             </shape>  
  52.         </clip>  
  53.     </item>  
  54. </layer-list>  
這裡面有3個item,分別為:background、secondProgress、progress,看名字就能知道其大概作用,我們比較關心的應該是後兩個,其實把這個檔案copy一份到自己的專案下,就可以隨心所欲的修改shape屬性:圓角、漸變等等。

自定義水平ProgressBar

第一步,在drawable資料夾下新建一個progressbar_horizontal_1.xml:

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <layer-list xmlns:android="http://schemas.android.com/apk/res/android" >  
  3.     <!-- background -->  
  4.     <item  
  5.         android:id="@android:id/background"
  6.         android:drawable="@drawable/progress_patch_green">  
  7.     </item>  
  8.     <!-- progress -->  
  9.     <item android:id="@android:id/progress">  
  10.         <clip>  
  11.             <nine-patch android:src="@drawable/progress_patch_galy" />  
  12.         </clip>  
  13.     </item>  
  14.     <!-- second progress -->  
  15.     <item android:id="@android:id/secondaryProgress">  
  16.         <clip>  
  17.             <nine-patch android:src="@drawable/progresspatch_blue" />  
  18.         </clip>  
  19.     </item>  
  20. </layer-list>  
上圖中的progress和secondprogress中src的資源便是我自定義的,注意這三個之間的疊放順序,background是最底層,中間的是progress最上層是second。

第二步,標準一點,在style中新建我們自定義的style:mProgress_horizontal:

  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,大功告成。

第三步,元件引用:

  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,如下:

  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系統樣式

  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為例進行探索,找到這個佈局檔案,原始碼如下:
  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原始碼,如下:
  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,如下:
  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. </rotate>  
第二步,在Style中定義mProgress_circle,如下:
  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>  
支援大小自己隨意定,別失真就好

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

  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:

  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引入:
  1. <prename="code"class="java"><itemname="android:indeterminateDrawable">@drawable/progress_circle_loading</item>

定義shape顏色 progress_circle_shape.xml

  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引入:
  1. <item name="android:indeterminateDrawable">@drawable/progress_circle_shape</item>  

效果圖如下:



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

最後來張全家福: