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



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" 
   <ProgressBar
        android:id="@+id/progressBar1"
        style="?android:attr/progressBarStyleHorizontal"
        style="@android:style/Widget.ProgressBar.Horizontal"(等同於@android:attr)
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

水平ProgressBar系統樣式

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

<pre name="code" class="java">    <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>
        <item name="android:mirrorForRtl">true</item>
    </style>

一眼看出android:progressDrawable便是主角,繼續看一下progress_horizontal的源碼,如下:

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2008 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->

<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>
這裏面有3個item,分別爲:background、secondProgress、progress,看名字就能知道其大概作用,我們比較關心的應該是後兩個,其實把這個文件copy一份到自己的項目下,就可以隨心所欲的修改shape屬性:圓角、漸變等等。


自定義水平ProgressBar

第一步,在drawable文件夾下新建一個progressbar_horizontal_1.xml:

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

    <!-- background -->
    <item
        android:id="@android:id/background"
        android:drawable="@drawable/progress_patch_green">
    </item>
    <!-- progress -->
    <item android:id="@android:id/progress">
        <clip>
            <nine-patch android:src="@drawable/progress_patch_galy" />
        </clip>
    </item>
    <!-- second progress -->

    <item android:id="@android:id/secondaryProgress">
        <clip>
            <nine-patch android:src="@drawable/progresspatch_blue" />
        </clip>
    </item>

</layer-list>
上圖中的progress和secondprogress中src的資源便是我自定義的,注意這三個之間的疊放順序,background是最底層,中間的是progress最上層是second。

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

    <style name="mProgress_horizontal">
        <item name="android:indeterminateOnly">false</item>
        <item name="android:progressDrawable">@drawable/progressbar_horizontal_1</item><!-- progress_horizontal -->
        <item name="android:indeterminateDrawable">@android:drawable/progress_indeterminate_horizontal</item>
        <item name="android:minHeight">20dip</item>
        <item name="android:maxHeight">20dip</item>
    </style>
上圖中prpgressDrawable資源便是指向了我們自定義的progressbar_horizontal_1,大功告成。

第三步,組件引用:

    <ProgressBar
        android:id="@+id/progressBar1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/progress_backround"
        android:padding="5dp"
        android:progress="50"
        style="@style/mProgress_horizontal"
        android:secondaryProgress="20"
        android:visibility="visible" />
【附】

在這裏我們也可以省略第二步創建style,直接在組件中android:progressDrawable引用自己的progressbar_horizontal_1,如下:

    <ProgressBar
        android:id="@+id/progressBar1"
        android:indeterminate="false"
        android:indeterminateOnly="false"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/progress_backround"
        android:padding="5dp"
        android:progress="50"
        android:maxHeight="20dp"
        android:minHeight="20dp"
        android:progressDrawable="@drawable/progressbar_horizontal_1"
        android:secondaryProgress="20"
        />

第四步,效果圖:




圓形ProgressBar系統樣式

    <ProgressBar
        android:id="@+id/progressBar2"
        style="@android:attr/progressBarStyleLarge"
        android:layout_gravity="center_vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
我們以progressBarStyleLarge爲例進行探索,找到這個佈局文件,源碼如下:

<style name="Widget.ProgressBar.Large">
  <item name="android:indeterminateDrawable">@android:drawable/progress_large_white</item>
  <item name="android:minWidth">76dip</item>
  <item name="android:maxWidth">76dip</item>
  <item name="android:minHeight">76dip</item>
  <item name="android:maxHeight">76dip</item>
</style>
同樣一眼看出indeterminateDrawable便是主角了,繼續看一下progress_large_white源碼,如下:

<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/spinner_white_76"
    android:pivotX="50%"
    android:pivotY="50%"
    android:fromDegrees="0"
    android:toDegrees="360" />
看到這裏就透徹了,就是在這裏spinner_white_76進行不停的旋轉的,我們copy一下這個文件,就可以直接自定義了。



自定義圓形ProgressBar

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

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/loading" //自定義的菊花圖片
    android:fromDegrees="0"
    android:pivotX="50%"
    android:pivotY="50%"
    android:toDegrees="360" >

</rotate>
第二步,在Style中定義mProgress_circle,如下:

    <style name="mProgress_circle">
        <item name="android:indeterminateDrawable">@drawable/progressbar_circle_1</item>
        <item name="android:minWidth">25dp</item>
        <item name="android:minHeight">25dp</item>
        <item name="android:maxWidth">60dp</item>
        <item name="android:maxHeight">60dp</item>
    </style>
支持大小自己隨意定,別失真就好

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

    <ProgressBar
        android:id="@+id/progressBar2"
        style="@style/mProgress_circle"
        android:layout_gravity="center_vertical"
        android:layout_width="match_parent"
        android:indeterminateDuration="1200"
        android:layout_height="wrap_content" />
【附】
上面是通過一張圖片填充android:indeterminateDrawable,我們也可以定義一個動畫或者自定義顏色(shape)來實現,跟圖片的用法一樣:

定義動畫 progress_circle_loading,xml:

<?xml version="1.0" encoding="UTF-8"?>  
<animation-list android:oneshot="false"  
  xmlns:android="http://schemas.android.com/apk/res/android">  
  <item android:duration="100" android:drawable="@drawable/loading_1" />  
  <item android:duration="100" android:drawable="@drawable/loading_2" />  
  <item android:duration="100" android:drawable="@drawable/loading_3" />  
  <item android:duration="100" android:drawable="@drawable/loading_4" />  
  <item android:duration="100" android:drawable="@drawable/loading_5" />  
  <item android:duration="100" android:drawable="@drawable/loading_6" />
</animation-list>
style的indeterminateDrawable引入:
<pre name="code" class="java"><item name="android:indeterminateDrawable">@drawable/progress_circle_loading</item>

定義shape顏色 progress_circle_shape.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="8"  
    android:useLevel="false" >  
    <gradient  
      android:centerColor="#FFFFFF"  
      android:centerY="0.50"  
      android:endColor="#1E90FF"  
      android:startColor="#000000"  
      android:type="sweep"  
      android:useLevel="false" />  
  </shape>  
</rotate>

style的indeterminateDrawable引入:

 <item name="android:indeterminateDrawable">@drawable/progress_circle_shape</item>


效果圖如下:





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


最後來張全家福:



發佈了95 篇原創文章 · 獲贊 123 · 訪問量 486萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章