ネット接続でデータをダウンロードには時間がかかることもあります。ロード中であることをユーザーに知らせることでユーザビリティが上がります。ProgressBar使うとダウンロードが何パーセントと簡単に表示できます。
2024.1.1
ProgressBar
ProgressBarはいくつかのstyleがあり、またコードを書かなくてもレイアウトで設定するだけで動きます。
- Widget.ProgressBar.Horizontal
- Widget.ProgressBar.Small
- Widget.ProgressBar.Large
- Widget.ProgressBar.Inverse
- Widget.ProgressBar.Small.Inverse
- Widget.ProgressBar.Large.Inverse
これらのstyleがあります。
Widget.ProgressBar
例えば、4つのstyleで試してみます。
LinearLayoutでやってみました。
activity_main.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <ProgressBar android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_margin="30dp" style="@android:style/Widget.ProgressBar.Small" /> <ProgressBar android:id="@+id/progressbar" android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_margin="30dp" style="@android:style/Widget.ProgressBar" /> <ProgressBar android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_margin="30dp" style="@android:style/Widget.ProgressBar.Large" /> <ProgressBar android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_margin="30dp" android:indeterminate="true" style="@android:style/Widget.ProgressBar.Horizontal" /> </LinearLayout> <!-- <?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:id="@+id/main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> --> |
Themeからのstyle
また、古い情報ではThemeのstyleを使うこともできるようです。
activity_main.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <ProgressBar android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_margin="30dp" style="?android:attr/progressBarStyleSmall" /> <ProgressBar android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_margin="30dp" style="?android:attr/progressBarStyle" /> <ProgressBar android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_margin="30dp" style="?android:attr/progressBarStyleLarge" /> <ProgressBar android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_margin="30dp" android:indeterminate="true" style="?android:attr/progressBarStyleHorizontal" /> </LinearLayout> |
微妙に違いがあります
これは Theme.AppCompat.Light.DarkActionBar をThemeとして設定している場合です。なのでThemeをカスタマイズすると変更できるところもあります。
また 「?android… 」としないと呼び出されません
1 |
style="?android:attr/progressBarStyle" |
またBarの色設定は ..\res\values\themes\themes.xml にあるcolorの設定でできます。
VISIBLE と INVISIBLE
例えば、ロードが始まったらProgressBarを表示させておき、終わりがわからない場合は進捗が表示できないのでそのままくるくる回転させておき、終わった時に非表示にすればいいのではないでしょうか。
表示・非表示はこれらを使います。
1 2 3 4 5 |
// 表示 android.widget.ProgressBar.VISIBLE // 非表示 android.widget.ProgressBar.INVISIBLE |
まとめると
MainActivity.kt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
//package com.example.kotlinprogressbar import android.os.Bundle import androidx.activity.enableEdgeToEdge import androidx.appcompat.app.AppCompatActivity import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import com.example.kotlinprogressbar.databinding.ActivityMainBinding class MainActivity : AppCompatActivity() { private lateinit var binding: ActivityMainBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) ViewCompat.setOnApplyWindowInsetsListener(binding.root) { v, insets -> val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom) insets } var flg = false binding.button.setOnClickListener { if (flg) { binding.progressbar.visibility = android.widget.ProgressBar.VISIBLE flg = false } else { binding.progressbar.visibility = android.widget.ProgressBar.INVISIBLE flg = true } } } } |
ConstraintLayoutに変更してみました。
activity_main.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
<?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" android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_margin="30dp" style="@android:style/Widget.ProgressBar" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.05" /> <Button android:id="@+id/button" android:text="@string/button" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.2" /> </androidx.constraintlayout.widget.ConstraintLayout> |
strings.xml
1 2 3 4 |
<resources> <string name="button">YourAppName</string> <string name="button">Button</string> </resources> |
build.gradle
1 2 3 4 5 6 7 8 |
... android { ... buildFeatures { viewBinding = true } } ... |
これでProgressbarをボタンをタップして非表示・表示ができました。
古い動画ですが動きがわかります
ProgressBar.Horizontal
一方で、進捗がわかるようにしたい場合もあります。ProgressBar.Horizontalを使うとそのprogressをユーザーに提示できます。
レイアウトでindeterminateをfalseにする必要があります。
1 |
android:indeterminate="false" |
ボタンタップで10づつ増加して100まで Horizontal ProgressBar で表示するコードを書いてみます。
MainActivity.kt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
//package com.example.kotlinprogressbar import android.os.Bundle import androidx.activity.enableEdgeToEdge import androidx.appcompat.app.AppCompatActivity import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import com.example.kotlinprogressbar.databinding.ActivityMainBinding class MainActivity : AppCompatActivity() { private lateinit var binding: ActivityMainBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) ViewCompat.setOnApplyWindowInsetsListener(binding.root) { v, insets -> val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom) insets } // 水平プログレスバーの最大値を設定します binding.progressbar.max = 100 var value = 0 binding.button.setOnClickListener { value += 10 // progress binding.progressbar.progress = value // セカンダリ値 binding.progressbar.secondaryProgress = 70 } } } |
activity_main.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<?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" android:layout_height="20dp" android:layout_width="200dp" android:layout_margin="30dp" android:indeterminate="false" style="@android:style/Widget.ProgressBar.Horizontal" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.05" /> <Button android:id="@+id/button" android:text="@string/button" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.2" /> </androidx.constraintlayout.widget.ConstraintLayout> |
strings.xml
1 2 3 4 |
<resources> <string name="button">Your App Name</string> <string name="button">Button</string> </resources> |
build.gradle
1 2 3 4 5 6 7 8 |
... android { ... buildFeatures { viewBinding = true } } ... |
実行してみると
これを使って例えばネットからのデータダウンロードの進捗を表示することなどができます。
Reference:
ProgressBar | Android Developers