我们在看一些视频或者下载、听音乐的时候常常会看到一条线在走,其实就是我们的进度条,上一期我们讲了登录界面,通过一个简单的存储对象sharedpreferences,来存储登录数据实现记住密码和自动登录的功能,这一期,我们结合上一期的项目和的进度条实现一个这样的效果:
就是在我们的登录部分和自动登录的时候加入一个进度条对话框,看起来还是挺简单的,那么我们先从进度条入手;
1、新建一个进度条对象:
//4.1 创建一个进度条对话框
private void waiting(boolean isLogin){
if(isLogin){
progressDialog = new ProgressDialog(this);
progressDialog.setTitle("登录");
progressDialog.setMessage("正在登陆");
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setCancelable(false);
progressDialog.show();
//4.2 向线程发送信息来延时登录
handler.post(thread);
}else if(datas[2].equals("true")){
progressDialog = new ProgressDialog(this);
progressDialog.setTitle("登录");
progressDialog.setMessage("正在登陆");
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressDialog.setCancelable(false);
progressDialog.show();
handler.sendEmptyMessageDelayed(1,3000);
}
}
这里我们在上一期的基础上加了一个函数,就是登录等待的函数,就是做了一个创建进度条对话框的功能,我们使用new ProgressDialog(this);来创建一个进度条对话框对象,然后通过一系列的set方法来设置我们对话框的内容,前面有讲过对话框的设置,如果有不清楚的地方就去翻一下,这里注意一个进度条的风格,我们使用setProgressStyle();设置风格,如果为ProgressDialog.STYLE_HORIZONTAL就是我们的水平线进度条,也就是我们点击登录的时候弹出来的那个样式,如果为ProgressDialog.STYLE_SPINNER就是自动登录的时候出现的圆环形的进度条,设置好之后我们就show()一下显示出来;
2、了解完进度条,还需要知道我们的线程,大家看到上面的点击登录的时候会有一个进度条对话框,它里面的线条是在走动的,而且有两个,一个是青色一个是灰色:
//4.3 因为是条形进度条,需要有一个进度的显示,所以我们需要创建线程
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
//4.4 我们在这个线程里实现增加进度
// 在这里设置进度条的数据
if(progress<100){
progress++;
if(subprogress < 100){
subprogress += 2;
}
//设置进度条的进度
progressDialog.setProgress(progress);
progressDialog.setSecondaryProgress(subprogress);
// 延长时间在进行,可以调整进度条的速度
handler.postDelayed(thread,5);
}else{
progressDialog.dismiss();
startIntent();
//4.5 数据更新
progress = 0;
subprogress = 0;
}
}
});
其实就是依靠线程让它动起来的,我们新建一个全局的线程并且写匿名内部类Raunnale,创建两个变量,一个是青色的进度条(progress),一个是灰色的进度条(subprogress),然后在子线程的run方法里面进行加加就可以了,记住我们需要给进度条设置好一个最大值,使用setMax(100)就可以,不过我这里没有设置,如果大家要设置就可以到waiting()函数里面show()的前面设置就可以,因为默认就是100,所以我就不设置了,而且我们的两个进度条的最大值都是100,所以这里写了一个if判断一下,因为我们以progress为准,所以就将subprogress放在里面就可以,而else里面就是我们在progress到达100之后打开登录界面的方法,progressDialog是我们创建的全局对象,就是要显示的对话框(总共就这些变量):
//1.1 定义变量
EditText ed_username2,ed_pwd2;
CheckBox cb_pwd,cb_remeber;
ProgressDialog progressDialog;
Handler handler;
String username , password,flag;
int progress,subprogress;
boolean complete;
//3.1 存储数据用的数组
String[] datas = new String[3];
使用它的dismiss()方法可以让其消失,然后调用我们上一期写的打开新实例的方法startIntent();
注意将我们的进度条清零,不然的话下次点击登录是不会在缓冲的;
3、handler的使用,我们可以看到在进度条没有到达100的时候会自动的不断加加,就有了一种前进的效果,其实就是handler这个对象一直在安排事件序列,让我们的子线程没隔5ms会执行一次,在waiting()函数里面有一句就和这里的
// 延长时间在进行,可以调整进度条的速度
handler.postDelayed(thread,5);
配合使用:
//4.2 向线程发送信息来延时登录
handler.post(thread);
还有一个就是我们自动登录时的圆环,它的是:
handler.sendEmptyMessageDelayed(1,3000);
然后配合:
handler = new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
if(msg.what == 1){
progressDialog.dismiss();
startIntent();
}
}
};
一起使用,就是发送一个信息,标号为1,延时为三秒,然后handler收到这个标号然后执行响应的函数,也是让对话框消失然后跳转到登录界面;
那么到底为什么要是用handler这个中介呢?因为Android的线程具有不安全性,不会让子线程直接更新我们的ui界面,所以就需要handler来安排子线程想要执行的操作,handler方法很多,可能以后还会用到,这里我就不详细解读,我们这一期主要就是了解进度条和这个项目怎么实现的问题;
4、在回过头来看一看整体的逻辑,
package com.example.qqloginactivity;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText;
public class QQloginActivity extends AppCompatActivity {
//1.1 定义变量
EditText ed_username2,ed_pwd2;
CheckBox cb_pwd,cb_remeber;
ProgressDialog progressDialog;
Handler handler;
String username , password,flag;
int progress,subprogress;
boolean complete;
//3.1 存储数据用的数组
String[] datas = new String[3];
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_qqlogin);
//1.3 函数调用
initparameters();
datas = Utils.readData(this);
if(datas!= null){
ed_username2.setText(datas[0]);
ed_pwd2.setText(datas[1]);
waiting(false);
}
}
//1.2 初始化变量
private void initparameters(){
ed_username2=findViewById(R.id.ed_username2);
ed_pwd2=findViewById(R.id.ed_pwd2);
cb_pwd=findViewById(R.id.cb_pwd);
cb_remeber=findViewById(R.id.cb_remeber);
handler = new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
if(msg.what == 1){
progressDialog.dismiss();
startIntent();
}
}
};
progress = 0;
subprogress = 0;
flag ="false";
complete = false;
}
public void onClick(View view) {
//2.1 拿到输入的数据然后判断
username = ed_username2.getText().toString();
password = ed_pwd2.getText().toString();
if(password.equals("123456")) {
//2.2 判断是否勾选记住密码
if (cb_pwd.isChecked()) {
Utils.appendData(this, username, password, flag);
if(cb_remeber.isChecked()){
flag = "true";
}else{
flag = "false";
}
Utils.updateLogin(this,flag);
} else {
Utils.deleteData(this);
}
//进入等待界面
waiting(true);
}
}
//3.2 启动实例
public void startIntent(){
//2.3 跳转页面
Intent intent = new Intent(this,TipsLoginActivity.class);
startActivity(intent);
}
//4.1 创建一个进度条对话框
private void waiting(boolean isLogin){
if(isLogin){
progressDialog = new ProgressDialog(this);
progressDialog.setTitle("登录");
progressDialog.setMessage("正在登陆");
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setCancelable(false);
progressDialog.show();
//4.2 向线程发送信息来延时登录
handler.post(thread);
}else if(datas[2].equals("true")){
progressDialog = new ProgressDialog(this);
progressDialog.setTitle("登录");
progressDialog.setMessage("正在登陆");
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressDialog.setCancelable(false);
progressDialog.show();
handler.sendEmptyMessageDelayed(1,3000);
}
}
//4.3 因为是条形进度条,需要有一个进度的显示,所以我们需要创建线程
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
//4.4 我们在这个线程里实现增加进度
// 在这里设置进度条的数据
if(progress<100){
progress++;
if(subprogress < 100){
subprogress += 2;
}
//设置进度条的进度
progressDialog.setProgress(progress);
progressDialog.setSecondaryProgress(subprogress);
// 延长时间在进行,可以调整进度条的速度
handler.postDelayed(thread,5);
}else{
progressDialog.dismiss();
startIntent();
//4.5 数据更新
progress = 0;
subprogress = 0;
}
}
});
}
第一个不同:就在上一期代码的基础上,我们新建了一个线程和一个waiting()函数,子线程用来实现进度条的前进,而waiting就是创建进度条,在刚开始的那个判断登录的时候,我们调用waiting函数,这个函数有一个参数,是用来我是自动登录还是点击登录的,所以自动登录是传的是false,然后就会创建一个圆环形的进度条,延时3s之后就会自动登录,当然,如果比较卡的话就可能没看到三秒就登陆了;
第二个不同就是在点击登陆的时候我们也是调用waiting()函数,但是执行的是线性的进度条对话框,然后让子线程跑起来,这里要注意跳转的问题,我们不要通过发送信息的方式,让handler安排跳转事件给主线程执行,因为这样会导致严重的延迟,而且含有bug,我们就让子线程开启实例就可以,所以可以看到我在progress大于100的时候
}else{
progressDialog.dismiss();
startIntent();
//4.5 数据更新
progress = 0;
subprogress = 0;
}
让对话框消失加上打开实例和清零数据;
好了,这一期就到这,加了一个简简单单的进度条对话框,还等什么,快去试试吧!