前言:最近Android開發需要做一個彈出框進度條,經過幾天的學習調研,現在在這裡總結一下。
Android中一開始對進度條的實作是通過ProgressDialog,可以彈出一個對話框,對話框裡顯示進度條。但是ProgressDialog在8.0以後被遺棄了,雖然也可以用,但是官方不推薦使用。相應的替代品就是ProgressBar。ProgressBar是一個布局,隻能寫在xml檔案中,而ProgressDialog可以在java代碼中實作。
下面先來看一下ProgressDialog的用法,我一共設定了四種dialog,最後一種就是我需要的彈出框進度條,并且是計時進度條。

先看activity_main.xml,内容比較簡單,就是設定了幾個button,用來彈出相應的彈出框。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<Button
android:onClick="putong"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="普通對話框"
/>
<Button
android:onClick="danxuan"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="單選對話框"
/>
<Button
android:onClick="duoxuan"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="多選對話框"
/>
<Button
android:onClick="jindutiao"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="進度條對話框"
/>
</LinearLayout>
下面看MainActivity中的代碼:每個彈出框的布局都在相應的函數中實作,四個函數對應四個彈出框。進度條彈出框用的是ProgressDialog,如何計時用的系統時間,最下面寫了一個StartTimer函數和EndTimer函數來進行計時操作,到達規定的時間則完成進度條,如果中途退出通過ProgressDialog的dismiss()來清除彈出框。
package com.example.hello;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.util.Timer;
import java.util.TimerTask;
public class MainActivity extends AppCompatActivity {
private int progress = 0;
private Timer timer;
private TimerTask timerTask;
private ProgressDialog dialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void putong(View view) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("普通對話框");
builder.setMessage("這是一個空白的對話框");
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
System.out.println("點了确定");
}
});
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
System.out.println("點了取消");
}
});
//調用show才能顯示出來
builder.show();
}
//點選按鈕彈出一個單選對話框
public void danxuan(View view) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("請選擇您喜歡的課程");
final String items[] = {"web開發", "android開發", "web前段", "ios開發", "鹹魚"};
//-1代表沒有條目被選中
builder.setSingleChoiceItems(items, -1, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//1.把選中的條目取出來
String item = items[which];
Toast.makeText(getApplicationContext(),item.toString(), Toast.LENGTH_LONG).show();
//2.然後把對話框關閉
dialog.dismiss();
}
});
builder.show();
}
//多選對話框
public void duoxuan(View view) {
System.out.println("點選了");
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("你喜歡哪個明星");
final String items[] = {"cxk", "趙麗穎", "“霸道總裁”黃曉明", "黃渤", "徐峥", "胡歌"};
final boolean [] checkedItems ={true,false,false,false,false,true};
builder.setMultiChoiceItems(items, checkedItems, new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
}
});
//把選中的挑選出來
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
StringBuffer sb = new StringBuffer();
//把選中的條目的資料取出來
for (int i = 0; i <checkedItems.length ; i++) {
//判斷下選中的
if(checkedItems[i]){
String fruit = items[i];
sb.append(fruit+"");
}
Toast.makeText(getApplicationContext(),sb.toString(),Toast.LENGTH_LONG).show();
//2.然後把對話框關閉
dialog.dismiss();
}
}
});
builder.show();
}
//進度加載框
public void jindutiao(View view) {
dialog = new ProgressDialog(this);
dialog.setTitle("請長按");
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setMax(10);
dialog.setProgress(0);
StartTimer();
dialog.dismiss();
dialog.show();
}
//activity啟動後開始計時
@Override
protected void onResume() {
super.onResume();
//StartTimer();
}
//進入背景後計時器暫停
@Override
protected void onPause() {
super.onPause();
//EndTimer();
}
public void StartTimer() {
//如果timer和timerTask已經被置null了
if (timer == null&&timerTask==null) {
//建立timer和timerTask
timer = new Timer();
timerTask = new TimerTask() {
@Override
public void run() {
//每次progress加一
progress++;
//如果進度條滿了的話就再置0,實作循環
if (progress == 11) {
dialog.dismiss();
}
//設定進度條進度
dialog.setProgress(progress);
}
};
timer.schedule(timerTask, 1000, 1000);
}
}
public void EndTimer()
{
timer.cancel();
timerTask.cancel();
timer=null;
timerTask=null;
}
}
下面看一下ProgressBar的效果,可以看到他是在系統界面展示一個進度條,并不能以彈出對話框的形式來實作進度條的功能。
這裡是ProgressBar的相關代碼,就是在xml檔案中加了一個ProgressBar的布局,然後在MainActivity中進行展示出來。
<ProgressBar
android:id="@+id/progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
/>
<TextView
android:id="@+id/tvProgress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
MainActivity中的相關代碼:
public void putongjindutiao(View view) {
final ProgressBar bar= (ProgressBar) findViewById(R.id.progress);
final TextView textView= (TextView) findViewById(R.id.tvProgress);
new Thread(){
@Override
public void run() {
int i=0;
while(i<100){
i++;
try {
Thread.sleep(80);
} catch (InterruptedException e) {
e.printStackTrace();
}
final int j=i;
bar.setProgress(i);
runOnUiThread(new Runnable() {
@Override
public void run() {
textView.setText(j+"%");
}
});
}
}
}.start();
}
好了,到這裡彈出框已經講完了,其實結果還是不那麼令人滿意,我原本是計劃通過ProgressBar來實作彈出框進度條的,但是最後發現實作不了,雖然ProgressDialog也可以實作,但是畢竟現在已經不推薦使用這個控件了,誰知道什麼時候就會取消呢。如果小夥伴有更好的方法可以實作彈出框進度條,可以留言。
關注公衆号,擷取更多開發必備知識