Обновить индикатор выполнения в списке для загрузки нескольких файлов
Как обновить индикатор выполнения в ListView. Когда каждый индикатор выполнения связан с загрузкой файла и который выполняется через AsyncTask.
Функция будет:
- Каждый индикатор выполнения обновляется с процессом загрузки.
- Когда файл будет загружен, он будет сохранен на SD-карте.
- Будет добавлен сервис (выполняется на заднем плане.
- Когда один загруженный файл должен показывать "Complete" (не следует удалять список форм)
Я также использовал базу данных для загрузки файла. Список также зависит от вектора базы данных. Как я могу его реализовать. Я также попытался, но не получил решения.
Ниже приведены два скриншота для подробного описания:
![enter image description here]()
Я также пробовал этот код:
temp = databaseHandler.getAllNotifyNumber();
list_download = (ListView) findViewById(R.id.list_download);
myCustomAdapter = new MyCustomAdapter(mContext);
list_download.setAdapter(myCustomAdapter);
myCustomAdapter.notifyDataSetChanged();
for (int index = 0; index < temp.size(); index++) {
String url = "http://upload.wikimedia.org/wikipedia/commons/0/05/Sna_large.png";
grabURL(url);
}
Это маска AsyncTask:
public void grabURL(String url) {
new GrabURL().execute(url);
}
private class GrabURL extends AsyncTask<String, Integer, String> {
protected String doInBackground(String... urls) {
String filename = "MySampleFile.png";
File myFile = new File(directory, filename);
try {
URL url = new URL(urls[0]);
URLConnection connection = url.openConnection();
connection.connect();
int fileSize = connection.getContentLength();
InputStream is = new BufferedInputStream(url.openStream());
OutputStream os = new FileOutputStream(myFile);
byte data[] = new byte[1024];
long total = 0;
int count;
while ((count = is.read(data)) != -1) {
total += count;
publishProgress((int) (total * 100 / fileSize));
os.write(data, 0, count);
}
os.flush();
os.close();
is.close();
} catch (Exception e) {
e.printStackTrace();
}
return filename;
}
@Override
protected void onProgressUpdate(Integer... progress) {
// home_countprogress.setVisibility(View.VISIBLE);
// home_countprogress.setText(String.valueOf(progress[0]) + "%");
// progressbar_horizontal.setProgress(progress[0]);
myCustomAdapter.notifyDataSetChanged();
}
@Override
protected void onCancelled() {
Toast toast = Toast.makeText(getBaseContext(),
"Error connecting to Server", Toast.LENGTH_LONG);
toast.setGravity(Gravity.TOP, 25, 400);
toast.show();
}
@Override
protected void onPostExecute(String filename) {
// progressbar_horizontal.setProgress(100);
// home_countprogress.setVisibility(View.VISIBLE);
}
protected void onPreExecute() {
// progressbar_horizontal.setVisibility(View.VISIBLE);
// progressbar_horizontal.setProgress(0);
// home_countprogress.setVisibility(View.VISIBLE);
myCustomAdapter = new MyCustomAdapter(mContext);
}
}
Ответы
Ответ 1
Вместо того, чтобы уведомлять ваш адаптер каждый раз, когда ваш прогресс изменяется (что все время), и делая это полностью неэффективным, вы можете попытаться сделать следующее.
- Создание пользовательского представления для каждой строки в ListView
- Добавьте метод, который называется 'setData()' или что-то еще. Вызвать это в обратном вызове getView() адаптера, установив данные для этого представления.
- Внутри 'setData()' регистрирует это представление как слушателя для обновлений прогресса из задачи async.
- Переопределите onStartTemporaryDetach() и onDetachedFromWindow() внутри своего пользовательского представления. Убедитесь, что вы отменили регистрацию от обновлений асинхронной задачи там (иначе вы получите утечку памяти).
- В вашей асинхронной задаче просто уведомите всех зарегистрированных слушателей (которые, вероятно, хранятся на карте URL-адресов слушателям или что-то в этом роде).
Ответ 2
Вместо использования ListView попробуйте следующее:
создайте макет, содержащий ваши вещи + ProgresseBar, это будет похоже на это
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="3dp">
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/image"
android:visibility="gone" />
</LinearLayout>
а в макете вашей активности/фрагмента замените ListView на LinearLayout (или LinearLayout внутри ScrollView) с теми же свойствами, что и ваш список:
<ScrollView
android:id="@+id/scrollView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
</LinearLayout>
</ScrollView
и в вашей деятельности создайте функцию:
private void addMyView(String url){
LayoutInflater mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View mView = mInflater.inflate(R.layout.my_layout, null, false);
ProgressBar mBar = (ProgressBar) mView.findViewById(R.id.progress);
container.addView(mView);
grabURL(url); // starting your task here
}
Также не забудьте свой LinearLayout:
LinearLayout container = (LinearLayout) findViewById(R.id.container);
тогда:
for (int index = 0; index < temp.size(); index++) {
String url = "http://upload.wikimedia.org/wikipedia/commons/0/05/Sna_large.png";
addMyView(url);`enter code here
}
Надеюсь, что помогите:)