【问题标题】:How to update and display a ProgressBar in each row of a ListView如何在 ListView 的每一行中更新和显示 ProgressBar
【发布时间】:2015-03-23 22:08:01
【问题描述】:

我想在我的 ListView 的每个视图中显示一个 ProgressBar。

为了更新视图中的进度条,我创建了一个扩展 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;
    }

我的异步持有者类如下:

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>

我尝试了很多不同的方法来完成这项工作。有人可以向我解释我做错了什么吗?

谢谢。

【问题讨论】:

  • mList 是如何构造和传递其内容的?文本是否也在移动,还是只是进度条?
  • mList 是 ProgressBarTasks 的列表。当我单击不同片段中的按钮时,一个新的列表项(行)被添加到 mList 并且 ProgressBar 立即启动。
  • 返回的ProgessBarTask 是否可能不是您所期望的?您的进度百分比文本是否也混淆了,还是只是进度条?
  • 是的,百分比文本也弄混了。我一直在阅读 ListView 将在滚动进入/退出视图时自动尝试重新使用列表项。我相信这可能是我需要控制的事情,但我无法弄清楚如何确保物品是有序的,并且只有正确的物品从异步任务中更新。
  • 是的,它称为视图回收,出于性能原因,您需要使用它。

标签: android android-listview android-progressbar


【解决方案1】:

问题是当你滚动时,position 5 的位置现在——例如——现在是 1。

然后您的代码显示mList.get(1),而您实际查找的ProgressBarTaskmList.get(5),因为它是在position 5 创建时存储在mList 中的。

简而言之,当内容少于一页时,position 仅对应于 mList 的正确索引。一旦滚动,索引就会“不同步”。

考虑使用ArrayAdapter 让您的生活更轻松。

【讨论】:

  • 好的,谢谢,我会尝试使用 ArrayAdapter 而不是 BaseAdapter。
  • @McGee,如果您觉得我帮助了您,请考虑接受我的回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多