進度條我們都很常見了,新的設計規范中提出了各式各樣的進度條,本篇就會介紹大部分進度條的實現。實現方式和規范的示例圖可能略有差異,還是那句話根據具體需求進行改變吧。
PS:本文較長
參考文檔:http://design.1sters.com/material_design/components/progress-activity.html
我們先來看設計規范中的一段話:進度條(指示器)的類型有兩種:線形進度指示器和圓形進度指示器。你可以使用其中任何一項來指示確定性和不確定性的操作。
線性進度條:
<1>Determinate:有精准進度的進度條,這個進度條就是通常我們看到的樣子,從無到有慢慢增加至滿格。
<2>InDeterminate:不精准的進度條,這個進度條會一直在那里走來走去,無法告訴用戶當前的精確進度。這個一般用於加載某個未知大小的東西,顯示時間一般比較短暫。
<3>Buffer:緩沖進度條。這個進度條可以分為三個層級。1.整體的長度,用虛線段表示。2.已經緩沖好的進度,用透明度較低的進度條表示。3.當前的進度,用透明度255的顏色區域表示,用來指示當前的進度。可以類比加載優酷視頻的情況。
<4>Query Indeterminate and Determinate:這個名字不知道誰起出來的,又長又詭異。其實就是剛開始沒精准進度,一會又可以顯示精准進度的進度條,在中國人的叫法中可以交過多狀態進度條。
圓形進度條:
這個圓形進度條顯示的是不精准進度,可以用來做起始的加載界面。比如下拉刷新啥的,右側的進度條用到了google設計中常見的三色動畫,有濃濃的google風范。
一、不顯示精准進度的圓形進度條
1.1 導入到自己的工程中
首先還是下載lib,然后添加支持,並且寫好命名空間。
https://github.com/navasmdc/MaterialDesignLibrary
添加lib支持后我們就可以用這個控件了,放入布局文件前還是要寫命名空間的。
xmlns:app="http://schemas.android.com/apk/res-auto"
<com.gc.materialdesign.views.ProgressBarCircularIndeterminate android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_margin="5dp" />
由於自定義控件在編譯器中不能實時顯示的問題,這里是完全透明的一個view,在實際運行后就能看到效果了。
1.2 在布局文件中設置各種參數
控件整體的大小,我這里強烈建議用寬高比1:1的方式來設定,因為它是圓形的,如果不是1:1就會出現bug。
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#ff0000" 進度條的顏色,默認是藍色
app:ringWidth="8dp" 進度條圓環的寬度,默認是4dp
1.3 通過代碼進行各種設置
package com.example.hhh; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; import com.gc.materialdesign.views.ProgressBarCircularIndeterminate; public class ProgressCircularTest extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.progressbar_circular); ProgressBarCircularIndeterminate progressBar = (ProgressBarCircularIndeterminate)findViewById(R.id.progressBar); progressBar.setBackgroundColor(0xffff0000);// 設置背景 progressBar.setBackgroundColor(getResources().getColor(R.color.orange));// 設置背景 progressBar.setRingWidth(8);// 設置圓環寬度 } }
二、不顯示精准進度的水平進度條
如何導入工程,如何寫命名空間,如何設置背景色我就不說了,和上面的圓形進度條完全一樣。
左圖是在編譯器中預覽的樣子,右圖是實際運行的樣子。
<com.gc.materialdesign.views.ProgressBarIndeterminateDeterminate android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_margin="5dp" />
2.1 在布局文件中進行各種設置
android:layout_width="200dp"
android:layout_height="wrap_content"
設置顯示的寬和高,默認高是3dp。
2.2 通過代碼進行設置
package com.example.hhh; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; import com.gc.materialdesign.views.ProgressBarIndeterminate; public class ProgressIndeterminateTest extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.progressbar_indeterminate); ProgressBarIndeterminate progressBar = (ProgressBarIndeterminate)findViewById(R.id.progressBar); progressBar.setBackgroundColor(0xffff0000);// 設定背景 progressBar.setBackgroundColor(getResources().getColor(R.color.orange));// 設定背景顏色 } }
三、顯示精准進度的水平進度條
這個進度條就是上面那個不精准進度條的父類,只不過這里我們可以設置它的精准進度,如最大最小值,當前的位置。但需要說明的一點,這個進度條只有通過代碼動態設置才能看到效果,僅僅通過布局文件是沒有效果的。
<com.gc.materialdesign.views.ProgressBarDeterminate android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_margin="5dp" />
3.1 通過布局文件設定屬性
app:max="80" 設定最大進度
app:min="0" 設定最小進度
app:progress="40" 設置當前的進度
3.2 通過代碼進行各種設定並且動態設定進度
package com.example.hhh; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.v7.app.ActionBarActivity; import com.gc.materialdesign.views.ProgressBarDeterminate; public class ProgressDeterminateTest extends ActionBarActivity { ProgressBarDeterminate progressBar03; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.progressbar_determinate); ProgressBarDeterminate progressBar01 = (ProgressBarDeterminate)findViewById(R.id.progressBar01); progressBar01.setBackgroundColor(0xffff0000);// 設定背景 ProgressBarDeterminate progressBar02 = (ProgressBarDeterminate)findViewById(R.id.progressBar02); progressBar02.setBackgroundColor(getResources().getColor(R.color.orange));// 設定背景色 progressBar03 = (ProgressBarDeterminate)findViewById(R.id.progressBar03); progressBar03.setMin(10);// 最小值 progressBar03.setMax(80);// 最大值 progressBar03.setProgress(20);// 當前的進度 System.out.println("progress = "+progressBar03.getProgress()); progressTimer.start();// 開始動態改變進度 } Thread progressTimer = new Thread(new Runnable() { @Override public void run() { for(int i = progressBar03.getProgress(); i <= progressBar03.getMax(); i++){ try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } handler.sendEmptyMessage(i); } System.out.println("--------END:progress = "+progressBar03.getProgress()+"--------"); } }); Handler handler = new Handler(new Handler.Callback() { @Override public boolean handleMessage(Message msg) { progressBar03.setProgress(msg.what); System.out.println("--------CURRENT:progress = "+ progressBar03.getProgress() +"--------"); return false; } }); }
四、先不精准,之后顯示精准進度的進度條
這個進度條如果你不開始動態設置進度的話,它會一直在那里走來走去,當你開始給他設定進度后它就會變成可以顯示精准進度條的進度條。設置背景色,寬高什么的都和上面說的一樣,就不廢話了,直接說怎么用。
<com.gc.materialdesign.views.ProgressBarIndeterminateDeterminate android:layout_width="match_parent" android:layout_height="wrap_content"/>
4.1 通過布局文件設定屬性
你可以通過布局文件設定max和min的值,但是這樣是不推薦的,因為設定后體現不出這個不精准的狀態了。同時如果你通過布局文件設定progress的值,可能會在運行是出現錯誤。你想啊,這個剛開始是沒有精准進度的,你設定一個初始的進度,很不符合邏輯,如果你要設定初始的進度,你直接用可以顯示精准進度的進度條就好啦。所以,這里不是很推薦用xml進行設定。下面說怎么用java代碼進行設定,下面的代碼注釋中有一些說明,請大家仔細閱讀。
4.2 通過代碼進行各種設定 & 動態設定進度
package com.example.hhh; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.v7.app.ActionBarActivity; import com.gc.materialdesign.views.ProgressBarIndeterminateDeterminate; public class ProgressIndeterminateDeterminateTest extends ActionBarActivity { ProgressBarIndeterminateDeterminate progressBar03; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.progressbar_indeterminate_determinate); ProgressBarIndeterminateDeterminate progressBar01 = (ProgressBarIndeterminateDeterminate)findViewById(R.id.progressBar01); progressBar01.setBackgroundColor(0xffff0000); ProgressBarIndeterminateDeterminate progressBar02 = (ProgressBarIndeterminateDeterminate)findViewById(R.id.progressBar02); progressBar02.setBackgroundColor(getResources().getColor(R.color.orange)); progressBar03 = (ProgressBarIndeterminateDeterminate)findViewById(R.id.progressBar03); progressBar03.setMin(20);// 不建議用,建議從0開始 progressBar03.setMax(90); System.out.println("progress = "+progressBar03.getProgress()); /** * 不要在此設定progress,因為這里設置后就會默認不是第二次啟動。源碼里面會出現動畫對象空指針的問題 * 其實這個進度條在不顯示精准進度的時候進度是通過動畫來不斷改變的,所以設定這個progress沒有什么意義。 * 在開始走進度的時候,如果你要從起始進度開始,請自定義初始值,不要用getRropgress()來 * 獲取。原因同樣是因為progress是通過動畫改變的,動畫結束的位置可能獲取到的進度是60. * 總之請不要在真正開始走進度的前來通過getProgress()來做什么操作。 */ //progressBar03.setProgress(30);// error! thread.start(); } Thread thread = new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(4000);// 先等3秒再開始走進度 for(int i = progressBar03.getMin(); i <= progressBar03.getMax(); i++){ Thread.sleep(100); handler.sendEmptyMessage(i); } System.out.println("--------END:progress = " + progressBar03.getProgress() +"--------"); } catch (InterruptedException e) { e.printStackTrace(); } } }); Handler handler = new Handler(new Handler.Callback() { @Override public boolean handleMessage(Message msg) { progressBar03.setProgress(msg.what); System.out.println("--------CURRENT:progress = "+ progressBar03.getProgress() + "--------"); return false; } }); }