如何在 ListView 的每一行中更新和显示 ProgressBar
How to update and display a ProgressBar in each row of a ListView
我想在我的 ListView 的每个视图中显示一个 ProgressBar。
我创建了一个 holder class,它扩展了 AsyncTask 以更新视图中的进度条。
除非我尝试滚动 ListView,否则我当前的实现工作正常。滚动后错误的进度条被更新,一些以前完成的进度条从当前 运行.
的位置开始。
我正在扩展BaseAdapter,我的getView方法如下:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (convertView == null) {
LayoutInflater li = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = li.inflate(R.layout.list_item, null);
}
ProgressBarTask asyncViewHolder = mList.get(position);
if(asyncViewHolder != null){
asyncViewHolder.setViews(view);
if (asyncViewHolder.getStatus() == AsyncTask.Status.PENDING) {
asyncViewHolder.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}
return view;
}
我的Async持有者class如下:
public class ProgressBarTask extends AsyncTask<Void, Integer, Void> {
private static final String TAG = ProgressBarTask.class.getName().toString();
private String title;
public TextView mProgressTitle;
public ProgressBar mProgressBar;
public TextView mProgressPercent;
public ProgressBarTask(String text){
title = text;
}
public void setViews(View base){
mProgressTitle = (TextView) base.findViewById(R.id.progress_title);
mProgressBar = (ProgressBar) base.findViewById(R.id.progress_horizontal);
mProgressPercent = (TextView) base.findViewById(R.id.progress_percent);
@Override
protected Void doInBackground(Void... ignore) {
for (int i = 0; !isCancelled() && i < 100; i++) {
if(i%5 == 0){
Log.i(TAG, title + " publishProgress(" + i + "%)");
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
publishProgress(i);
}
return null;
}
@Override
protected void onProgressUpdate(Integer... percent) {
if(percent[0]%5 == 0){
Log.i(TAG, title +" onProgressUpdate(" + percent[0] + "%)");
}
mProgressBar.setProgress(percent[0] * mProgressBar.getMax() / 100);
mProgressPercent.setText(percent[0] + "%");
}
...
...
}
而我的list_item描述如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/list_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/progress_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:paddingLeft="8dp"
android:paddingTop="8dp"
android:text="Progress:"
android:textAppearance="?android:attr/textAppearanceLarge" />
<ProgressBar
android:id="@+id/progress_horizontal"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:max="213"
android:padding="8dp" />
<TextView
android:id="@+id/progress_percent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingBottom="8dp"
android:text="0%"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
我尝试了很多不同的方法来完成这项工作。有人可以向我解释我做错了什么吗?
谢谢。
问题是当你滚动时,position
5 处的内容现在——例如——现在是 1。
你的代码然后说 mList.get(1)
,而你实际要查找的 ProgressBarTask
是 mList.get(5)
,因为它是在 position
5 存储时创建的mList
.
简而言之,position
仅在内容少于一页时对应mList
的正确索引。一旦滚动,索引就会变成 "out of sync".
考虑使用 ArrayAdapter
让您的生活更轻松。
我想在我的 ListView 的每个视图中显示一个 ProgressBar。
我创建了一个 holder class,它扩展了 AsyncTask 以更新视图中的进度条。
除非我尝试滚动 ListView,否则我当前的实现工作正常。滚动后错误的进度条被更新,一些以前完成的进度条从当前 运行.
的位置开始。我正在扩展BaseAdapter,我的getView方法如下:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (convertView == null) {
LayoutInflater li = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = li.inflate(R.layout.list_item, null);
}
ProgressBarTask asyncViewHolder = mList.get(position);
if(asyncViewHolder != null){
asyncViewHolder.setViews(view);
if (asyncViewHolder.getStatus() == AsyncTask.Status.PENDING) {
asyncViewHolder.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}
return view;
}
我的Async持有者class如下:
public class ProgressBarTask extends AsyncTask<Void, Integer, Void> {
private static final String TAG = ProgressBarTask.class.getName().toString();
private String title;
public TextView mProgressTitle;
public ProgressBar mProgressBar;
public TextView mProgressPercent;
public ProgressBarTask(String text){
title = text;
}
public void setViews(View base){
mProgressTitle = (TextView) base.findViewById(R.id.progress_title);
mProgressBar = (ProgressBar) base.findViewById(R.id.progress_horizontal);
mProgressPercent = (TextView) base.findViewById(R.id.progress_percent);
@Override
protected Void doInBackground(Void... ignore) {
for (int i = 0; !isCancelled() && i < 100; i++) {
if(i%5 == 0){
Log.i(TAG, title + " publishProgress(" + i + "%)");
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
publishProgress(i);
}
return null;
}
@Override
protected void onProgressUpdate(Integer... percent) {
if(percent[0]%5 == 0){
Log.i(TAG, title +" onProgressUpdate(" + percent[0] + "%)");
}
mProgressBar.setProgress(percent[0] * mProgressBar.getMax() / 100);
mProgressPercent.setText(percent[0] + "%");
}
...
...
}
而我的list_item描述如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/list_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/progress_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:paddingLeft="8dp"
android:paddingTop="8dp"
android:text="Progress:"
android:textAppearance="?android:attr/textAppearanceLarge" />
<ProgressBar
android:id="@+id/progress_horizontal"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:max="213"
android:padding="8dp" />
<TextView
android:id="@+id/progress_percent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingBottom="8dp"
android:text="0%"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
我尝试了很多不同的方法来完成这项工作。有人可以向我解释我做错了什么吗?
谢谢。
问题是当你滚动时,position
5 处的内容现在——例如——现在是 1。
你的代码然后说 mList.get(1)
,而你实际要查找的 ProgressBarTask
是 mList.get(5)
,因为它是在 position
5 存储时创建的mList
.
简而言之,position
仅在内容少于一页时对应mList
的正确索引。一旦滚动,索引就会变成 "out of sync".
考虑使用 ArrayAdapter
让您的生活更轻松。