在RecyclerView中更新ProgressBar

时间:2015-04-26 16:27:11

标签: android android-recyclerview

我有一个RecyclerView。其中,项目具有标准布局 - 一个TextView和一个ProgressBar。 项目在运行时添加到recyclerview。 每当添加一个Item时,都会启动一个更新ProgressBar的AsyncTask。 AsynTask保存了RecyclerView Adapter对ProgressBar对象的引用。 当回收站视图中的项目太多时会发生此问题。

我知道RecyclerView会回收任何旧视图,因此想要了解至少为进度条提供的方法。

实现这一目标的理想方法是什么?

以下是适配器的摘录

final List<Country> cuntries = toObservable[
  const Country('Afghanistan', 'AF'),
  const Country('Åland Islands', 'AX')}]

另外,我正在使用notifydatasetchanged将项目添加到RecyclerView。

3 个答案:

答案 0 :(得分:4)

有点晚了,但我找到了让它运转的方法。

我的recyclerview包含大量的查看者,只有一个查看者有一个进度条。我有一个sqlite数据库,我在其中维护用于在我的服务和活动之间进行同步的标识符(以识别recyclerview中哪些视图需要更新)。

根据您的实现,您必须找到一种方法来识别哪个广播事件对应于哪个适配器项。我已经给出了我在下面所做的简化版本。

进度条模型:

class ProgressModel{
    String progressId;
    int progress = 0;
}

public int getProgress(){
    return progress;
}

ViewHolder:

public class ProgressViewHolder extends RecyclerView.ViewHolder {
    private ProgressBar mProgressBar;

    public ProgressViewHolder(View itemView) {
        mProgressBar = (ProgressBar) itemView.findViewById(R.id.mProgressBar);
    }

    public ProgressBar getProgressBar() {
        return mProgressBar;
    }   
}

在recyclerview适配器中,

@Override
public void onBindViewHolder(ProgressViewHolder holder, int position) {
    ProgressModel item = mData.get(position);
    int progress = item.getProgress();
        if (progress > 0) {
            ProgressBar downloadProgress = holder.getProgressBar();
            if (downloadProgress.isIndeterminate()) {
                downloadProgress.setIndeterminate(false);
            }
            downloadProgress.setProgress(progress);
        }
}

public void refresh(position, ProgressModel item){
    mData.set(position, item);
    notifyItemChanged(position);
}

在实现的Activity中填充视图,创建自身的静态实例并将其传递给BroadcastReceiver。我花了很长时间才发现静态实例是必需的,否则即使我调用notifyItemchanged(),视图也不会改变。

public class MainActivity extends Activity{
    private static MainActivity instance;
    private MyReceiver mReceiver;
    private MyAdapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        instance = this;
        mReceiver = new MyReceiver(instance);
        //TODO: Initialize adapter with data and set to recyclerview
    }

    public void update(Intent intent){
        ProgressModel model = new ProgressModel ();
        //TODO: set progress detail from intent to model and get position from progressId
        instance.mAdapter.refresh(position,model);
    }

    private static class MyReceiver extends BroadcastReceiver {
        MainActivity activity;

        public DownloadReceiver(MainActivity activity) {
            this.activity = activity;
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            //pass intent with progress details to activity
            activity.update(intent);
        }
    }

}

希望这有帮助。

答案 1 :(得分:0)

您可以简单地使用回收者视图的“ findViewHolderForAdapterPosition”方法,然后从中获得一个viewHolder对象,然后将该viewHolder转换为适配器viewholder,以便您可以直接访问该Viewholder的视图,(在这种情况下,我们访问progressBar)< / p>

以下是科特林的示例代码

 /**
     * update progress bar in recycler view
     * get viewHolder from position and progress bar from that viewHolder
     *  we are rapidly updating progressbar so we did't use notify method as it always update whole row instead of only progress bar
     *  @param position : position of list cell
     *  @param progress : new progress value
     */
    private fun updateDownloadProgressBar(position :Int, progress:Int)
    {
        val viewHolder = recyclerViewDownload.findViewHolderForAdapterPosition(position)
        (viewHolder as ViewHolderDownload).progressBarDownload.progress=progress
    }

答案 2 :(得分:0)

对于那些刚接触Android开发人员并且只知道Java的人,可能会对@Mayank Sharma提供的上述代码感到困惑,效果很好,我给出了他回答的Java版本:

void updateProgress(int position, int progress)
{
    MyAdapter.MyHolder mHolder =
            (MyAdapter.MyHolder) myRecyclerView.findViewHolderForAdapterPosition(position);
    mHolder.customProgress.setProgress(progress);
}

在您的活动中创建上述方法,其中您的回收站视图包含进度条,并在需要进度条进行任何更改时调用此方法。

相关问题