ProgressBar используется для отображения состояния выполняемой работы, например какого-либо анализа, загрузки файла и так далее.
Чтобы добавить ProgressBar на активность, достаточно определить его в коде разметки.
<ProgressBar android:id="@+id/progress" android:layout_width="wrap_content" android:layout_height="wrap_content" />
По умолчанию, ProgressBar представляет собой вращающееся колесо, однако имеется возможность также в виде горизонтальной полосы. Для этого достаточно добавить атрибут style и выбрать горизонтальный стиль.
<ProgressBar android:id="@+id/progress" android:layout_width="150dp" android:layout_height="150dp" style="@style/Widget.AppCompat.ProgressBar.Horizontal" />
ProgressBar поддерживает два режима работы: детерминированный и неопределенный.
Неопределенный режим используется, когда вы не знаете, сколько времени займёт выполнение работы. По умолчанию ProgressBar использует неопределенный режим и показывает циклическую анимацию без показа достигнутого значения прогресса.
Детерминированный режим используется, когда нужно показать прогресс выполнения работы. Например, процент скачивания файла. Задать прогресс можно либо через XML, либо программно.
- Через XML
В коде разметки нужно добавить атрибут android:progress и передать в него уровень достигнутого прогресса.<ProgressBar android:id="@+id/progress" android:layout_width="150dp" android:layout_height="150dp" android:progress="50" style="@style/Widget.AppCompat.ProgressBar.Horizontal" />
По умолчанию максимальный прогресс равен 100, однако его можно изменить с помощью атрибута android:max.
<ProgressBar android:id="@+id/progress" android:layout_width="150dp" android:layout_height="150dp" android:max="150" android:progress="50" style="@style/Widget.AppCompat.ProgressBar.Horizontal" />
- Программно
В коде активности нужно определить экземпляр ProgressBar и затем указать прогресс с помощью метода setProgress(), в аргументы которого передаётся значение прогресса.ProgressBar progressBar = findViewById(R.id.progress); progressBar.setProgress(50);
Кроме того, можно не задавать конкретный прогресс, а увеличивать текущий на определенную величину. Для этого можно воспользоваться методом incrementProgressBy().
progressBar.setProgress(40); // прогресс = 40 progressBar.incrementProgressBy(50); // прогресс = 90
Аналогично способу в XML, можно программно задать максимальное значение прогресса следующим образом.
progressBar.setMax(150);
Если вам нужно узнать текущий прогресс, либо максимальное значение, вы можете воспользоваться методами getProgress() и getMax() соответственно.
ProgressBar progressBar = findViewById(R.id.progress); progressBar.setProgress(40); Toast.makeText(this, "Прогресс - " + progressBar.getProgress() + "\nМаксимальное значение - " + progressBar.getMax(), Toast.LENGTH_SHORT).show();
Допустим, нам нужно скачать какой-либо файл из Интернета, отображая прогресс загрузки на экране. Разместим на активности ProgressBar и Button, который будет запускать загрузку.
Поскольку загрузка может быть весьма затратной по ресурсам операцией, её лучше всего выполнять в отдельном потоке, возвращая в основной только результат выполнения. Поэтому создадим класс DownloadTask, наследующий от AsyncTask. Его задачей будет являться загрузка файла.
public class DownloadTask extends AsyncTask<String, Integer, Boolean> { public interface DownloadListener { void onDownloadComplete(File filename); void onProgressUpdate(int progress); void onDownloadFailure(final String msg); } private final DownloadListener listener; private String msg; private File saveTo; public DownloadTask(DownloadListener listener) { this.listener = listener; } @Override protected Boolean doInBackground(String... params) { if (params == null || params.length < 2) { msg = "Incomplete parameters"; return false; } String sUrl = params[0]; String filename = params[1]; File rootDir = Environment.getExternalStorageDirectory(); saveTo = new File(rootDir, filename); try { URL url = new URL(sUrl); URLConnection conn = url.openConnection(); conn.connect(); int fileLength = conn.getContentLength(); InputStream is = new BufferedInputStream(url.openStream()); OutputStream os = new FileOutputStream(saveTo); byte buffer[] = new byte[512]; long totalDownloaded = 0; int count; while ((count = is.read(buffer)) != -1) { totalDownloaded += count; publishProgress((int) (totalDownloaded * 100 / fileLength)); os.write(buffer, 0, count); } os.flush(); os.close(); is.close(); return true; } catch (MalformedURLException e) { msg = "Invalid URL"; } catch (IOException e) { msg = "No internet connection"; } return false; } @Override protected void onProgressUpdate(Integer... values) { if (listener != null) listener.onProgressUpdate(values[0]); } @Override protected void onPostExecute(Boolean result) { if (!result) { if (listener != null) listener.onDownloadFailure(msg); return; } if (listener != null) listener.onDownloadComplete(saveTo); } }
Также в этом классе добавлен интерфейс DownloadListener, с помощью которого в основной поток будет передаваться прогресс загрузки, а также результат операции.
У класса AsyncTask уже реализован метод onProgressUpdate(), который позволяет возвращать прогресс выполнения операции. Чтобы передать в него значения, нужно вызвать метод publishProgress() внутри doInBackground().
Определим ProgressBar и Button в коде активности и добавим для кнопки слушатель, внутри которого будет запускаться AsyncTask, выполняющий загрузку файла. Прогресс операции будет обновляться в методе интерфейса onProgressUpdate(), куда передаётся текущее значение прогресса.
progressBar = findViewById(R.id.progress); btn_start = findViewById(R.id.btn_start); btn_start.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { String url = "https://imagine.gsfc.nasa.gov/Images/news/G306_color_large.jpg"; String filename = "G306.jpg"; DownloadTask downloadTask = new DownloadTask(new DownloadTask.DownloadListener() { @Override public void onDownloadComplete(File filename) { Toast.makeText(getApplicationContext(), filename + " загружен", Toast.LENGTH_SHORT) .show(); } @Override public void onProgressUpdate(int progress) { progressBar.setProgress(progress); } @Override public void onDownloadFailure(String msg) { Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show(); } }); downloadTask.execute(url, filename); } });
Также можно выводить значение в процентах под ProgressBar, добавив текстовых полей.