Добавление ProgressBar в ListView/OnClick, вызываемое один раз

Идея состоит в том, чтобы иметь список элементов, в котором после нажатия на элемент ProgressBar будет медленно заполняться по мере выполнения задачи. Например, представьте список файлов с кнопкой «Загрузить» для каждого из них. При нажатии кнопки загрузки файл загружается в фоновом режиме, и заполняется индикатор выполнения, показывающий, насколько файл близок к завершению.

Для этого я создаю AsyncTask, который время от времени вызывает notifyDataSetChanged на адаптере, чтобы перерисовать его. Хотя это работает после нажатия одной кнопки, до завершения AsyncTask я не могу нажимать другие кнопки в ListView. Может кто-нибудь, пожалуйста, скажите мне, что я делаю неправильно?

Я запускаю это на эмуляторе (x86 )на Ice Cream Sandwich.

У меня есть DownloadItem для представления хода загрузки (приведенный ниже код упрощен для краткости):

class DownloadItem {
    public String name;       // Name of the file being downloaded
    public Integer progress;  // How much is downloaded so far
    public Integer length;    // Size of the file
}

Затем у меня есть ArrayAdapter, который адаптирует список DownloadItem для ListView :

class DownloadArrayAdapter extends ArrayAdapter {
    List mItems;
    public DownloadArrayAdapter(List items) {
      mItems = items;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row = convertView;
        if(row == null) {
            // Inflate
            Log.d(TAG, "Starting XML inflation");
            LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            row = inflater.inflate(R.layout.download_list_item, parent, false);
            Log.d(TAG, "Finished XML inflation");
        }

        DownloadItem item = mItems.get(position);

        ProgressBar downloadProgressBar = (ProgressBar) row.findViewById(R.id.downloadProgressBar);
        Button downloadButton = (Button) row.findViewById(R.id.downloadButton);

        downloadButton.setTag(item);
        downloadProgressBar.setMax(item.length);
        downloadProgressBar.setProgress(item.progress);

        return row;
    }
}

. Пока все хорошо -, список корректно отображается. В моей деятельности у меня есть onClickListener:

class DownloadActivity extends Activity {
    //...
    public void onDownloadButtonClick(View view) {
        DownloadItem item = (DownloadInfo)view.getTag();
        DownloadArrayAdapter adapter = (DownloadArrayAdapter) view.getAdapter();
        new DownloadTask(adapter, item).execute();
        //new DownloadTask(adapter, item).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR)
    }
}

Я пробовал это с executeOnExecutor, а также просто выполнить, но безуспешно. DownloadTask:

class DownloadTask extends AsyncTask {
    ArrayAdapter mAdapter;
    DownloadItem mItem;

    public DownloadTask(ArrayAdapter adapter, DownloadItem item) {
        mItem = item;
    }

    //Dummy implementation
    @Override
    public Void doInBackground(Void... params) {
        for(int i=0; i

Это работает -почти. Когда я делаю это, после нажатия одной кнопки ProgressBar обновляется как обычно -, но я не могу нажимать другие кнопки в ListView, пока AsyncTask не вернется. То есть onDownloadButtonClick никогда не вызывается. Если я удаляю вызов mAdapter.notifyDataSetChanged ()из функции onProgressUpdate, несколько задач обновляются одновременно, но, конечно, список не становится недействительным, поэтому мне приходится прокручивать его, чтобы увидеть изменения.

Что я делаю не так, и как я могу это исправить?

Редактировать :Я еще немного поиграл с этим, и кажется, что частота вызова notifyDataSetChanged влияет на то, вызывается ли onClick или просто теряется. С приведенным выше кодом, отчаянно щелкая, я могу иногда запускать вторую полосу загрузки. Если я увеличу Thread.Sleep до чего-то гораздо большего, например 2000, список будет работать так, как я изначально ожидал.

Итак, новый вопрос -, как мне заставить ProgressBars плавно обновляться, не блокируя вызов onClick?

РЕДАКТИРОВАТЬ #2 :Я отправил пример проекта с этой проблемой в свою учетную запись GitHub:https://github.com/mdkess/ProgressBarListView

6
задан mindvirus 29 June 2012 в 03:48
поделиться