今天要來講講關於Android跑進度條或轉圈圈的這個UI操作

首先我想說一句..

 

進度條一定是人類偉大發明之一(/・0・)

我在寫這篇文章的時候,我想到了我以前看過啾啾鞋的的這支影片

https://www.youtube.com/watch?v=aXrtO9oBTvo

 

裡面他就說到了關於UI設計風格對於人類的感官會產生何種現象(-‿◦)

 

那麼常見的進度處理UI中,撇開太特殊的不要講

大多常見的就是轉圈圈跟跑進度條兩種

也就是這種

Minimal SVG Loading Spinner In Pure JS - LoadingSpinner.js | CSS Script

 

跟這種

Xamarin.Forms ProgressBar - Xamarin | Microsoft Docs

 

Okay,那麼在Android之中,這些東西會如何被實踐呢?

這就是今天的重點啦~

 

事不宜遲,上範例

 

然後本次沒有GitHub~โ๏∀๏ใ

此外,這篇會沿用到一點背景執行的觀念

不太了解的可以去看看這篇

->碼農日常-『Android studio』Android背景執行之Thread、Handler及AsyncTask的基礎用法

 


 

1.繼續廢話&給你介面

 

上面有提到,太複雜的進度條不是本篇的重點XD

進度條千奇百怪,什麼奇怪的UI都有

講明白點很有可能單一個進度條就是一個工程師2天的工作量(囧)

當然如果直接拿系統原生的UI就是2分鐘的工作量(咦?)

 

It's Real! - Benny Sisko | Meme Generator

 

所以就知道啦!要畫一個精美的UI是一件多麻煩的事

你~各位啊,要惜福!知不知道QQ

 

好的講爽了,現在給你一下今天的介面吧

 

activity_main.xml

截圖 2020-11-01 下午1.07.15

 

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/button_Run"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"

        android:text="跑一次進度"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.5" />

    <Button
        android:id="@+id/button_OpenSpinner"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="開啟轉圈圈Dialog"
        app:layout_constraintBottom_toTopOf="@+id/button_Run"
        app:layout_constraintEnd_toStartOf="@+id/guideline"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/button_OpenBar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="開啟跑條Dialog"
        app:layout_constraintBottom_toTopOf="@+id/button_Run"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="@+id/guideline"
        app:layout_constraintTop_toTopOf="parent" />

    <ProgressBar
        android:id="@+id/progressBar_Spinner"
        style="?android:attr/progressBarStyle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button_Run" />

    <ProgressBar
        android:id="@+id/progressBar_Bar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginEnd="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/progressBar_Spinner" />


</androidx.constraintlayout.widget.ConstraintLayout>

 

要顯示進度條ProgressBar的元件中大致有兩種方法

一種是直接在介面中拉喇進度條元件並對他做控制的做法

 

另一種是使用一種名為ProgressDialog的一個類別元件

但是如果你真的在程式碼的中打上ProgressDialog的話,程式碼會跳這個給你

截圖 2020-11-01 下午1.11.51

 

Emm...沒錯,會畫一個橫槓ヾ(´¬`)ノ

雖然畫橫槓,但目前還是可以用的(現在是2020年,不保證明年QQ)

也就是說畫橫槓的意思就是他們不推薦使用或是即將放棄使用

 

講是這樣講啦,不過這個元件我從剛開始學的時候大致就是這樣的用法了(2016年吧,Maybe)

目前也還沒真的廢棄掉,所以應該還行吧...應該。

 

那今天的操作主體就是這兩種在程式之中的寫法,繼續往下吧

 


 

2. 撰寫ProgressDialog

 

ProgressDialog 就是我剛剛所提到的被畫一條橫線的那位苦主了( ・ὢ・ )

ProgressDialog顧名思義,他就是在一個對話視窗中劃上UI圖標來做顯示的一種方式

整體大概就現這樣

 

轉圈圈

 

進度條

 

 

而我在猜他之所以會被不建議使用,原因大概就是出在自由度太低

講白了就像是開放世界的遊戲一樣,雖然很多時候常常找不到解任務的地點

但是因為很自由所以超級好玩(´∀`)

 

反過來說,我認為ProgressDialog就是因為限制多,不夠符合現今UI的設計模式,因此才不被建議使用

 

但是...有時候我就是想偷懶啊XDDDDDD

 

那麼來看看程式吧

 

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button btSpinner, btBar;
        btBar = findViewById(R.id.button_OpenBar);
        btSpinner = findViewById(R.id.button_OpenSpinner);
        /**Dialog進度條的範例*/
        btBar.setOnClickListener(v -> {
            ProgressDialog dialog = new ProgressDialog(this);
            /**設置UI形式為跑進度條*/
            dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            dialog.setTitle("跑進度中");
            dialog.setMax(120);
            dialog.show();
            new Thread(()->{
                for (int i = 0; i <120 ; i++) {
                    /**更新進度*/
                    dialog.setProgress(i);
                    SystemClock.sleep(50);
                }
                dialog.dismiss();
            }).start();
        });
        /**Dialog轉圈圈的範例*/
        btSpinner.setOnClickListener(v -> {
            ProgressDialog dialog = new ProgressDialog(this);
            /**設置UI形式為轉圈圈*/
            dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
            dialog.setTitle("跑進度中");
            dialog.show();
            new Thread(()->{
                for (int i = 0; i <100 ; i++) {
                    /**設置要告訴用戶的話*/
                    dialog.setMessage("進度已跑: "+i);
                    SystemClock.sleep(50);
                }
                dialog.dismiss();
            }).start();
        });
    }
}

 

其實說穿了,主要差異根本就只有在粉底白字的那兩個部分而已

不過如果要設置條狀的話,綠底白字的部分請記得要一併設置喔

 


 

3. 設置ProgressBar

 

Google後來在UI設計上,便把轉圈圈跟進度條分離出來,變成了一種可直接操作的元件

可以注意到上方介面檔案中,便有這兩個部分

 

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
    tools:context=".MainActivity">

                   .
                  (略)
                   .

    
    <ProgressBar
        android:id="@+id/progressBar_Spinner"
        style="?android:attr/progressBarStyle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button_Run" />

    <ProgressBar
        android:id="@+id/progressBar_Bar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginEnd="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/progressBar_Spinner" />


</androidx.constraintlayout.widget.ConstraintLayout>

 

在粉底白字的部分就是告訴程式我們要用哪種UI了

 

我先講轉圈圈的UI

基本上不需要設置任何東西,他自己就會轉XD

所以僅需設定他的出現與否即可

 

而進度條的部分,也是只要設置他的最大進度,並隨時更新進度條,也是非常好搞定

 

直接看程式最快了~

 

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button btRun;
        ProgressBar pgBar, pgSpinner;
        btRun = findViewById(R.id.button_Run);
        pgBar = findViewById(R.id.progressBar_Bar);
        pgSpinner = findViewById(R.id.progressBar_Spinner);
        /**初始時,設定使轉圈圈不可見*/
        pgSpinner.setVisibility(View.INVISIBLE);

        btRun.setOnClickListener(v -> {
            /**設置轉圈圈為可見*/
            pgSpinner.setVisibility(View.VISIBLE);
            /**進度條最多就是100*/
            pgBar.setMax(100);
            new Thread(()->{
                for (int i = 0; i <100 ; i++) {
                    /**更新進度*/
                    pgBar.setProgress(i);
                    SystemClock.sleep(50);
                }
                /**跑完後,設置轉圈圈為不可見*/
                pgSpinner.setVisibility(View.INVISIBLE);
                /**進度條歸零*/
                pgBar.setProgress(0);
                runOnUiThread(()->{
                    Toast.makeText(this, "進度跑完!", Toast.LENGTH_SHORT).show();
                });
            }).start();

        });
    }
}

 

基本上,直接複製過去就完成了設置

最後給你所有的程式碼吧!

 

MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button btSpinner, btBar, btRun;
        ProgressBar pgBar, pgSpinner;
        btBar = findViewById(R.id.button_OpenBar);
        btSpinner = findViewById(R.id.button_OpenSpinner);
        btRun = findViewById(R.id.button_Run);
        pgBar = findViewById(R.id.progressBar_Bar);
        pgSpinner = findViewById(R.id.progressBar_Spinner);
        /**初始時,設定使轉圈圈不可見*/
        pgSpinner.setVisibility(View.INVISIBLE);
        /**Dialog進度條的範例*/
        btBar.setOnClickListener(v -> {
            ProgressDialog dialog = new ProgressDialog(this);
            /**設置行事為跑進度條*/
            dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            dialog.setTitle("跑進度中");
            dialog.setMax(120);
            dialog.show();
            new Thread(()->{
                for (int i = 0; i <120 ; i++) {
                    /**更新進度*/
                    dialog.setProgress(i);
                    SystemClock.sleep(50);
                }
                dialog.dismiss();
            }).start();
        });
        /**Dialog轉圈圈的範例*/
        btSpinner.setOnClickListener(v -> {
            ProgressDialog dialog = new ProgressDialog(this);
            dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
            dialog.setTitle("跑進度中");
            dialog.show();
            new Thread(()->{
                for (int i = 0; i <100 ; i++) {
                    /**設置要告訴用戶的話*/
                    dialog.setMessage("進度已跑: "+i);
                    SystemClock.sleep(50);
                }
                dialog.dismiss();
            }).start();
        });

        btRun.setOnClickListener(v -> {
            /**設置轉圈圈開啟*/
            pgSpinner.setVisibility(View.VISIBLE);
            /**進度條最多就是100*/
            pgBar.setMax(100);
            new Thread(()->{
                for (int i = 0; i <100 ; i++) {
                    /**更新進度*/
                    pgBar.setProgress(i);
                    SystemClock.sleep(50);
                }
                /**跑完後,設置轉圈圈為不可見*/
                pgSpinner.setVisibility(View.INVISIBLE);
                /**進度條歸零*/
                pgBar.setProgress(0);
                runOnUiThread(()->{
                    Toast.makeText(this, "進度跑完!", Toast.LENGTH_SHORT).show();
                });
            }).start();

        });
    }
}

 


 

結語

 

今天沒有介紹很困難的東西,真是非常抱歉(??)

其實最近在寫Android相關知識上載題材的選擇遇上了一些瓶頸

畢竟我的文章風格就是廢話連篇XD

但是近幾日載題材的選擇上越來越少了

畢竟我持續寫了一年,真要寫成書了的話早就寫出了一本的份量了囧

為了這週要寫什麼我真的是考慮了很久啊QQQQQQQ

 

好啦那文章就寫到這,希望對你有幫助

覺得我文章不錯的話,幫我按推推+Like吧!

 

TK

arrow
arrow

    碼農日常 發表在 痞客邦 留言(6) 人氣()