-1

進度條無法顯示進度,如果沒有向下滾動,並再次返回到相同位置的訪問,詳細請查看本演示:失敗的AsyncTask更新進度的進度時,首先進入片段ListView控件,然後滾動ListView控件後沒事

https://www.youtube.com/watch?v=wGu8MyUHidQ&feature=youtu.be 

沒有異常或錯誤,也許ListView錯誤或邏輯錯誤,任何人有任何想法?

DownloadInfo類:

private final static String TAG = DownloadInfo.class.getSimpleName(); 
public enum DownloadState { 
    NOT_STARTED, 
    QUEUED, 
    DOWNLOADING, 
    COMPLETE 
} 
private volatile DownloadState mDownloadState = DownloadState.NOT_STARTED; 
private final String mFilename; 
private volatile Integer mProgress; 
private final Integer mFileSize; 
private volatile ProgressBar mProgressBar; 

public DownloadInfo(String filename, Integer size) { 
    mFilename = filename; 
    mProgress = 0; 
    mFileSize = size; 
    mProgressBar = null; 
} 
//Follow by getters & setters 

DownloadInfoArrayAdapter類:

public class DownloadInfoArrayAdapter extends ArrayAdapter<DownloadInfo> { 
private static class ViewHolder { 
    TextView textView; 
    ProgressBar progressBar; 
    Button button; 
    DownloadInfo info; 
} 

public DownloadInfoArrayAdapter(Context context, List<DownloadInfo> objects) { 
    super(context, objects); 
} 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    View row = convertView; 
    final DownloadInfo info = getItem(position); 

    ViewHolder holder = null; 

    if (null == row) { 
     LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     row = inflater.inflate(R.layout.file_download_row, parent, false); 

     holder = new ViewHolder(); 
     holder.textView = (TextView) row.findViewById(R.id.downloadFileName); 
     holder.progressBar = (ProgressBar) row.findViewById(R.id.downloadProgressBar); 
     holder.button = (Button) row.findViewById(R.id.downloadButton); 
     holder.info = info; 
     row.setTag(holder); 
    } else { 
     holder = (ViewHolder) row.getTag(); 
     holder.info.setProgressBar(null); 
     holder.info = info; 
     holder.info.setProgressBar(holder.progressBar); 
    } 

    holder.textView.setText(info.getFilename()); 
    holder.progressBar.setProgress(info.getProgress()); 
    holder.progressBar.setMax(info.getFileSize()); 
    info.setProgressBar(holder.progressBar); 

    holder.button.setEnabled(info.getDownloadState() == DownloadState.NOT_STARTED); 
    final Button button = holder.button; 
    holder.button.setOnClickListener(new OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      info.setDownloadState(DownloadState.QUEUED); 
      button.setEnabled(false); 
      button.invalidate(); 
      FileDownloadTask task = new FileDownloadTask(info); 
      task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 
     } 
    }); 
    return row; 
} 
} 

FileDownloadTask類:

@Override 
protected void onProgressUpdate(Integer... values) { 
    mInfo.setProgress(values[0]); 
    ProgressBar bar = mInfo.getProgressBar(); 
    if (bar != null) { 
     bar.setProgress(mInfo.getProgress()); 
     bar.invalidate(); 
    } 
} 

@Override 
protected Void doInBackground(Void... params) { 
    Log.d(TAG, "Starting download for " + mInfo.getFilename()); 
    mInfo.setDownloadState(DownloadState.DOWNLOADING); 
    for (int i = 0; i <= mInfo.getFileSize(); ++i) { 
     try { 
      Thread.sleep(16); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     publishProgress(i); 
    } 
    mInfo.setDownloadState(DownloadState.COMPLETE); 
    return null; 
} 

@Override 
protected void onPostExecute(Void result) { 
    mInfo.setDownloadState(DownloadState.COMPLETE); 
} 

@Override 
protected void onPreExecute() { 
    mInfo.setDownloadState(DownloadState.DOWNLOADING); 
} 

在片段添加點擊監聽

lvStickerGroup = (ListView) activity.findViewById(R.id.lvStickerGroup); 
    List<DownloadInfo> downloadInfo = new ArrayList<DownloadInfo>(); 
    for (int i = 0; i < 50; ++i) { 
     downloadInfo.add(new DownloadInfo("File " + i, 1000)); 
    } 

    adapter = new DownloadInfoArrayAdapter(activity, downloadInfo); 
    lvStickerGroup.setAdapter(adapter); 
    lvStickerGroup.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
     @Override 
     public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { 
      Toast.makeText(activity, "bla" + i, Toast.LENGTH_SHORT).show(); 
     } 
    }); 

    //Testing all below, no luck 
    ((BaseAdapter) adapter).notifyDataSetChanged(); 
    lvStickerGroup.invalidate(); 
    lvStickerGroup.invalidateViews(); 
    lvStickerGroup.refreshDrawableState(); 

    lvStickerGroup.post(new Runnable() { 
     public void run() { 
      for (int a = 0; a < lvStickerGroup.getCount(); a++) { 
       lvStickerGroup.setSelection(a); 
      } 
      for (int a = lvStickerGroup.getCount() - 1; a >= 0; a--) { 
       lvStickerGroup.setSelection(a); 
      } 
     } 
    }); 

我試圖以編程方式滾動到底部並返回頂部,同樣沒有運氣,除了編程方式滾動到項目位置時,在最初輸入片段時不會顯示在第一頁。

此外,我試圖在適配器上invalidate(),invalidateView()notifyDataSetChanged,同樣的問題發生,這可能是ListView的錯誤?

謝謝先進。

+0

視頻中有什麼奇怪的東西?請具體說明。 –

+0

第一次進入顯示ListView不會更新進度條的片段後,只有向下滾動並返回到相同的項目,只有進度條纔會顯示進度。進度條只是測試使用一些簡單的增量與睡眠16ms,它從ayncTask更新回UI ... –

+0

訪問[mcve]並按比例編輯您的問題。 –

回答

0

上面的代碼沒有錯,功能齊全。我發現谷歌ListView IO會議的線索

https://www.youtube.com/watch?v=wDBM6wVEO70 

ListView無法包裝內容,否則會出現錯誤。那爲什麼我遇到這樣的問題。