Issue
The progressbar cannot show progress if without scroll down and back to same position visit again, detail please check this demo:
https://www.youtube.com/watch?v=wGu8MyUHidQ&feature=youtu.be
No exception or error, maybe ListView bug or logic error, anyone have any idea?
DownloadInfo class:
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 Class:
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 class:
@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);
}
In the fragment add click listener
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);
}
}
});
I tried to programmatically scroll to bottom and back to top, same no luck, except programmatically scroll to the item position will not show in the first page when enter the fragment initially.
Besides, I tried to invalidate()
, invalidateView()
notifyDataSetChanged
on the adapter, same problem occurs, is it possibly a ListView
bug?
Solution
Nothing wrong with the code above, fully functional. I found the clue in Google ListView IO conference
https://www.youtube.com/watch?v=wDBM6wVEO70
ListView cannot wrap content, else will have bugs showing up. That why I experience such issue.
Answered By - Mr Hoelee
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.