Обновить индикатор выполнения в списке для загрузки нескольких файлов

Как обновить индикатор выполнения в 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
}

Надеюсь, что помогите:)