今天要來講講關於Android跑進度條或轉圈圈的這個UI操作
首先我想說一句..
進度條一定是人類偉大發明之一(/・0・)
我在寫這篇文章的時候,我想到了我以前看過啾啾鞋的的這支影片
https://www.youtube.com/watch?v=aXrtO9oBTvo
裡面他就說到了關於UI設計風格對於人類的感官會產生何種現象(-‿◦)
那麼常見的進度處理UI中,撇開太特殊的不要講
大多常見的就是轉圈圈跟跑進度條兩種
也就是這種
跟這種
Okay,那麼在Android之中,這些東西會如何被實踐呢?
這就是今天的重點啦~
事不宜遲,上範例
然後本次沒有GitHub~โ๏∀๏ใ
此外,這篇會沿用到一點背景執行的觀念
不太了解的可以去看看這篇
->碼農日常-『Android studio』Android背景執行之Thread、Handler及AsyncTask的基礎用法
1.繼續廢話&給你介面
上面有提到,太複雜的進度條不是本篇的重點XD
進度條千奇百怪,什麼奇怪的UI都有
講明白點很有可能單一個進度條就是一個工程師2天的工作量(囧)
當然如果直接拿系統原生的UI就是2分鐘的工作量(咦?)
所以就知道啦!要畫一個精美的UI是一件多麻煩的事
你~各位啊,要惜福!知不知道QQ
好的講爽了,現在給你一下今天的介面吧
activity_main.xml
<?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的話,程式碼會跳這個給你
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吧!
留言列表