Как мне обновить состояние ProgressBar для каждого элемента GridView / ListView? - PullRequest
3 голосов
/ 14 ноября 2011

В настоящее время у меня есть GridView, и каждый элемент должен иметь отдельный ProgressBar. Элементы представляют отдельные загрузки, и я хотел бы показать состояние загрузок с использованием этих ProgressBars.

Но как мне их обновить? Моя проблема заключается в том, что в соответствии с документами (и тем, что я слышал в видео Google IO), единственный способ обновить элементы в AdapterViews - это обновить назначенный адаптер и вызывать .notifyDatasetChanged () после каждого обновления. *

Конечно, это действительно работает и в этом случае, но обновления происходят довольно часто (5-10 секунд в секунду). И вызов .notifyDatasetChanged на этой частоте прерывает любое взаимодействие с GridView. Например. пользователь пытается долго щелкнуть по элементу в сетке, но событие щелчка останавливается, потому что для обновления хода загрузки был вызван файл .notifyDatasetChanged.

Есть ли другой способ сделать это? Должен ли я отказаться от AdapterViews и использовать что-то еще?

Ответы [ 2 ]

2 голосов
/ 15 ноября 2011

Для таких ситуаций, как ваша, с частыми обновлениями (много раз в секунду), notifyDatasetChanged - неправильный путь - вам нужно обновить отдельные представления напрямую.

Не видя ваш код и взаимосвязь между загрузкой файла и записью в GridView, трудно сказать, какие именно вызовы вам понадобятся, но:

-GridView имеет "getChildAt", который вы можете использовать, чтобы получить представление по определенному индексу.
Нет смысла обновлять вид, если он даже не виден. Если он не находится между getFirstVisiblePosition () и getLastVisiblePosition (), игнорируйте его, он будет отображаться с обновленными данными всякий раз, когда перерисовывается.

0 голосов
/ 14 ноября 2011

Я сделал это в одном проекте. Вы можете обновить пользовательский интерфейс, если используете Asysctask без .notifyDatasetChanged (). Например, у меня есть метод загрузки в моем Utils. * класс * 1001

public static String downloadFile(DownloadItem downItem, AsynBackGroundFileLoader asynBackGroundFileLoader, String fileName,
            String fileURL) {
                // Spiking my code 
            while (bufferLength = inputStream.read(buffer) > 0 ) {
                    fileOutput.write(buffer, 0, bufferLength);
                // add up the size so we know how much is downloaded
                downloadedSize += bufferLength;

                // this is where you would do something to report the progress,
                int pro = ((int) (downloadedSize * 100 / totalSize));

                asynBackGroundFileLoader.updateProgress(pro);

            }
    }

И в моей AsyncTask

public class AsynBackGroundFileLoader extends AsyncTask < Void , Integer , String > {



public AsynBackGroundFileLoader (DownloadItem dItem , TableLayout progressBarHodler , UpgradeActivity listener ) {
        try {
            mDownloadingProgressBarHolder = progressBarHodler ;
            this.mDownloadingProgressBarHolder.setVisibility ( View.VISIBLE ) ;

            mDownloadingProgressBar = ( ProgressBar ) mDownloadingProgressBarHolder.findViewById ( R.id.downloading_progress_bar ) ;
            downloadCancelButton = ( ImageButton ) mDownloadingProgressBarHolder.findViewById ( R.id.downloading_progress_cancel_btn ) ;
            downloadCancelButton.setImageResource ( R.drawable.btn_cancel );

    @ Override
    protected void onPreExecute ( ) {

    }

    @ Override
    protected String doInBackground ( Void ... params ) {

            boolean loadSuccess = Utils.downloadFile ( downItem , this , mFileName , downItem.getLink ( ) ) ;
        return ""+loadSuccess ;
    }

    @ Override
    protected void onPostExecute ( String result ) {

    }

    public void updateProgress ( int progressPercentage ) {
        try {
            if ( progressPercentage < 0 ) {
                progressPercentage = 0 ;
            } else if ( progressPercentage > 100 ) {
                progressPercentage = 100 ;
            }

//Here I am updating my UI without making list to notifyDataChanged()
                currentCompletedProgress = progressPercentage ;
                // This is my progressbar in UI that update , I got this progressbar by passing UI item view in constructor 
                mDownloadingProgressBar.setProgress ( progressPercentage ) ;
                downItem.setTotalProgress ( currentCompletedProgress ) ;
            } catch ( Exception e ) {
                Log.e ( TAG , "Exception = " + e.toString ( ) ) ;
                e.printStackTrace ( ) ;
            }

        }

    public ProgressBar getmDownloadinProgressBar ( ) {
        return mDownloadingProgressBar ;
    }
}

Я начинаю загрузку, когда пользователь лижет строку списка

public void onItemClick(AdapterView<?> tempadapter, View view, int position, long arg3) {
    TableLayout table = ((TableLayout) view.findViewById(R.id.downloading_progress_holder));
    DownloadItem temp = adapter.items.get(position);

        AsynBackGroundFileLoader bgdownloader = new AsynBackGroundFileLoader(temp, table, UpgradeActivity.this);
        bgdownloader.execute();
    }

    table.setVisibility(View.VISIBLE);
}
...