Material Designer的低版本兼容实现(十三)—— ProgressBar
进度条我们都很常见了,新的设计规范中提出了各式各样的进度条,本篇就会介绍大部分进度条的实现。实现方式和规范的示例图可能略有差异,还是那句话根据具体需求进行改变吧。
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; } }); }