第33讲 UI组件_进度条ProcessBar和消息队列处理器handler
第33讲UI组件_进度条ProcessBar和消息队列处理器handler
1. 进度条ProcessBar
一个可视化的进度指示器,代表正在执行的耗时任务。可以为用户展示一个进度条,表示正在执行的任务的进度。
当程序不能或者不需要确定任务执行的准确进度时,ProgressBar也可以只显示一个循环的圆圈。
默认情况下,ProcessBar显示的是一个无限循环的圆圈,可以通过样式的配置,实现一个水平方向的进度条。
XML重要属性
android:progressBarStyle: 默认进度条样式
android:progressBarStyleHorizontal: 水平样式
重要方法
getMax(): 返回这个进度条的范围的上限
getProgress(): 返回进度
getSecondaryProgress(): 返回次要进度
incrementProgressBy(int diff): 指定增加的进度
isIndeterminate(): 指示进度条是否在不确定模式下
setIndeterminate(boolean indeterminate): 设置不确定模式下
setVisibility(int v): 设置该进度条是否可视
style="@android:style/Widget.ProgressBar.Horizontal" /*水平方向的进度条,其他值可以是
Widget.ProgressBar.Horizontal,Widget.ProgressBar.Small,Widget.ProgressBar.Large,
Widget.ProgressBar.Inverse,Widget.ProgressBar.Small.Inverse,Widget.ProgressBar.Large.Inverse*/
android:max="100" //总长度
android:progress="29" //初始值
//进度条加减
public void add(View view) {
progressBar.incrementProgressBy(10); //指定增加10的进度
}
public void reduce(View view) {
progressBar.incrementProgressBy(-10); //指定增加-10的进度
}
、UI阻塞(第10讲有相关讲解)
使用ProcessBar主要是在执行耗时任务时,此时需要注意UI阻塞问题。
1、post方法 解决UI阻塞
首先利用Thread(new Runnable() 对耗时任务进行包装;
之后,由于需要修改UI当中的组件(例如,移除ProcessBar),因此需要将其放置在任务队列中,利用view.post()方法进行包装。
public void test(final View view) {
new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(7000);
} catch (InterruptedException e) {
e.printStackTrace();
}
view.post(new Runnable() { //把任务放置在任务队列中
public void run() {
ViewGroup group=(ViewGroup)progressBar.getParent();
group.removeView(progressBar); // 移除ProcessBar
}
});
}
}).start();
}
3. handler消息队列处理器
post方法虽然发送的是一个实现了Runnable接口的类对象,但是它并非创建了一个新线程,而是执行了该对象中的run方法。也就是说,整个run中的操作和主线程处于同一个线程。
这样对于那些简单的操作,似乎并不会影响。但是对于耗时较长的操作,就会出现“假死”。为了解决这个问题,就需要使得handler绑定到一个新开启线程的消息队列上,在这个处于另外线程的上的消息队列中处理传过来的Runnable对象和消息。
Handler基本概念:
Handler主要用于异步消息的处理:当发出一个消息之后,首先进入一个消息队列,发送消息的函数即刻返回,而另外一个部分逐个的在消息队列中将消息取出,然后对消息进行出来,就是发送消息和接收消息不是同步的处理。
这种机制通常用来处理相对耗时比较长的操作。
注意:1.Handler对象的实例化,要在UI
线程当中完成。
调用handler的post方法可以为UI线程的消息队列添加一个Runnable消息。
2、handler方法
利用handler的post方法打开runnable注入任务队列。
public class MainActivity extends Activity{
private ProgressBar progressBar;
private Handler handler=new Handler();
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressBar=(ProgressBar) findViewById(R.id.progressBar1);
new Thread(new Runnable(){
public void run() {
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.post(newRunnable() {
public void run() {
ViewGroup group=(ViewGroup) progressBar.getParent();
group.removeView(progressBar);
TextView textView=new TextView(MainActivity.this);
textView.setText("下载完成!");
group.addView(textView);
}
});
}
}).start();
}
}
3、利用handler实现进度条随时间递增
要设置一个flag标记是否进度条到达最大;
在循环过程中,会出现已经删除了ProgressBar但是继续循环删除找不到该View的情况,因此还需要判断是否已经删除了。
private ProgressBar progressBar;
private Handler handler = new Handler();
private Boolean flag = true;
protected void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressBar = (ProgressBar) findViewById(R.id.progressBar1);
new Thread(new Runnable() {
public void run() {
while (flag) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.post(new Runnable() {
public void run() {
if (progressBar.getProgress() ==progressBar.getMax()) {
// 删除进度条,添加提示
ViewGroup group = (ViewGroup)progressBar.getParent();
if (group != null) {
group.removeView(progressBar);
TextView textView = newTextView(MainActivity.this);
textView.setText("下载完成!!");
group.addView(textView);
flag = false;
}
}
progressBar.incrementProgressBy(10);
}
});
}
}
}).start();
}
第33讲 UI组件_进度条ProcessBar和消息队列处理器handler的更多相关文章
- 第34讲 UI组件之 ProgressDialog和Message
第34讲UI组件之 ProgressDialog和Message 1.进度对话框 ProgressDialog <1>简介 ProgressDialog是AlertDialog类的一个扩展 ...
- 第25讲 UI组件之 AlertDialog 的各种实现
第25讲 UI组件之AlertDialog 的各种实现 对话框(Dialog)是程序运行中的弹出窗口,例如当用户要删除一个联系方式时,会弹出一个对话框. Android提供了多种对话框:警告对话框(A ...
- 第32讲 UI组件之 时间日期控件DatePicker和TimePicker
第32讲 UI组件之 时间日期控件DatePicker和TimePicker 在Android中,时间日期控件相对来说还是比较丰富的.其中, DatePicker用来实现日期输入设置, Time ...
- 第31讲 UI组件之 Gallery画廊控件
第31讲 UI组件之 Gallery画廊控件 1.Gallery的简介 Gallery(画廊)是一个锁定中心条目并且拥有水平滚动列表的视图,一般用来浏览图片,并且可以响应事件显示信息.Gallery只 ...
- 第30讲 UI组件之 GridView组件
第30讲 UI组件之 GridView组件 1.网格布局组件GridView GridView是一个ViewGroup(布局控件),可使用表格的方式显示组件,可滚动的控件.一般用于显示多张图片,比如实 ...
- 第29讲 UI组件之 ListView与 BaseAdapter,SimpleAdapter
第29讲 UI组件之 ListView与 BaseAdapter,SimpleAdapter 1.BaseAdapter BaseAdapter是Android应用程序中经常用到的基础数据适配器,它的 ...
- 第28讲 UI组件之 ListView和ArrayAdapter
第28讲 UI组件之 ListView和ArrayAdapter 1. Adapter 适配器 Adapter是连接后端数据和前端显示的适配器接口,是数据和UI(View)之间一个重要的纽带.在常见的 ...
- 第27讲 UI组件之 ScrollView与底部动态添加数据
第27讲 UI组件之 ScrollView与底部动态添加数据 1. ScrollView(滚动视图) ScrollView(滚动视图)是实现滚动的一个控件,只需要将需要滚动的控件添加到ScrollVi ...
- 第19讲- UI组件之_Button、checkbox、radio
第19讲 UI组件之_Button.checkbox.radio 四.按钮Button Button继承自TextView,间接继承自View.当用户对按钮进行操作的时候,触发相应事件,如点击,触摸. ...
随机推荐
- [教程] 神器i9100刷基带与内核的方法!(兼带ROOT方法)
http://bbs.hiapk.com/thread-2647905-1-1.html ------何为基带?何为内核? 为什么刷基带,为什么刷内核?!!! 基带:基带(Baseband)是手机中的 ...
- checkbox 与JS的应用
JS是一种基于(面向)对象的语言.所有的东西都基本上是对象. 基于对象和面向对象概念上基本上没有什么区别. js没有类,它把类功能称为原型对象.是同一个概念.主要是因为js没有class关键字.类== ...
- 魔方公式xyz
x:(整个魔方以R的方向转动),x':(整个魔方以R'的方向转动) y:(整个魔方以U的方向转动),y':(整个魔方以U'的方向转动) z:(整个魔方以F的方向转动),z':(整个魔方以F'的方向 ...
- html中编写js的方式
第一种:引用外部的js文件 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http ...
- HID 报告描述符精细说明.
1,报告描述符概述 1.1) 报表描述符 报表描述符和USB的其他描述符是不一样的,它不是一个简单的表格,报表描述符是USB所有描述符中最复杂的.报表描述符非常复杂而有弹性,因为它 ...
- Linq 学习(1) 概述
本篇简单回顾C#语言集合操作的变化,通过与Linq对等的面向对象的语法来认识Linq.Linq是Language Integrated Query, 初识Linq感觉跟SQL Server的Tsql很 ...
- IActiveView 接口 - 浅谈
IActiveView 和 IMap以其 Map, PageLayout之间的关系. 在ArcMap中, PageLayout 和 Map分别对应不同的视图: layout 和data view.在同 ...
- Swift--集合类型 数组 字典 集合
数组 1.创建一个数组 var someInts = [Int]()空数组 someInts = []清空 var threeDoubles = Array(repeating: 0.0, count ...
- java 判断对象是否是某个类的类型方法
class Do1 { public static void main(String[] args) { AA a=new CC(); if(a instanceof CC) { CC b=(CC)a ...
- 动态绑定、阻止继承,final类和方法
1.编译器查看对象的声明类型和方法名.当调用 x.f(param); 且隐式参数x生命为C类对象.这时候可能有多个名字都叫f,但是参数类型不一样的方法.编译器会一一列举C类中名为f的方法和其超类中访问 ...