本文介绍了使用底部的 ProgressBar 将项目添加到 Endless Scroll RecyclerView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遵循了 Vilen 对 SO 的出色回答:在 RecyclerView 网格中放置一个不确定的进度条作为页脚,了解如何使用 ProgressBar 实现无限滚动的 RecyclerView.

I followed Vilen's excellent answer on SO: Put an indeterminate progressbar as footer in a RecyclerView grid on how to implement an endless scroll recyclerview with ProgressBar.

我自己实现了它并且它有效,但我想扩展这个例子.我想在 recyclerview 的顶部添加额外的项目,类似于 Facebook 在添加新状态更新时的做法.

I implemented it myself and it works but I would like to extend the example. I want to add extra items at the top of the recyclerview, similar to how Facebook does it when you add a new status update.

我无法成功地将额外的项目添加到列表中 - 这是我在他的 MainActivity 中添加到 Vilen 代码中的代码:

I was not able to add extra items onto the list successfully - here is my code that I added onto Vilen's code in his MainActivity:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    int id = item.getItemId();

    if (id == R.id.add) {
        myDataset.add(0, "Newly added");
        mRecyclerView.smoothScrollToPosition(0);
        mAdapter.notifyItemInserted(0);
}
return super.onOptionsItemSelected(item);
}

当我点击添加"按钮时:

When I clicked the "Add" button:

当我向下滚动时,我得到两个微调器而不是一个:

When I scroll down, I get two spinners instead of one:

当微调器完成并加载了接下来的 5 个项目时,微调器仍在那里:

When the spinners finish and the next 5 items are loaded, the spinner is still there:

我做错了什么?

推荐答案

问题是当您添加新项目时,内部 EndlessRecyclerOnScrollListener 不知道它并且计数器中断.事实上,EndlessRecyclerOnScrollListener 的回答有一些限制和可能的问题,例如如果您一次加载 1 个项目,它将无法正常工作.所以这是一个增强版.

The problem is that when you add new item internal EndlessRecyclerOnScrollListener doesn't know about it and counters breaking.As a matter of fact answer with EndlessRecyclerOnScrollListener has some limitations and possible problems, e.g. if you load 1 item at a time it will not work. So here is an enhanced version.

  1. 去掉 EndlessRecyclerOnScrollListener 我们不再需要它了
  2. 将您的适配器更改为包含滚动侦听器的适配器

  1. Get rid of EndlessRecyclerOnScrollListener we don't need it anymore
  2. Change your adapter to this which contains scroll listener

public class MyAdapter<T> extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private final int VIEW_ITEM = 1;
    private final int VIEW_PROG = 0;

    private List<T> mDataset;

    // The minimum amount of items to have below your current scroll position before loading more.
    private int visibleThreshold = 2;
    private int lastVisibleItem, totalItemCount;
    private boolean loading;
    private OnLoadMoreListener onLoadMoreListener;

    public MyAdapter(List<T> myDataSet, RecyclerView recyclerView) {
        mDataset = myDataSet;

        if (recyclerView.getLayoutManager() instanceof LinearLayoutManager) {

            final LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
            recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
                @Override
                public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                    super.onScrolled(recyclerView, dx, dy);

                    totalItemCount = linearLayoutManager.getItemCount();
                    lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition();
                    if (!loading && totalItemCount <= (lastVisibleItem + visibleThreshold)) {
                        // End has been reached
                        // Do something
                        if (onLoadMoreListener != null) {
                            onLoadMoreListener.onLoadMore();
                        }
                        loading = true;
                    }
                }
            });
        }
    }

    @Override
    public int getItemViewType(int position) {
        return mDataset.get(position) != null ? VIEW_ITEM : VIEW_PROG;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        RecyclerView.ViewHolder vh;
        if (viewType == VIEW_ITEM) {
            View v = LayoutInflater.from(parent.getContext())
                    .inflate(android.R.layout.simple_list_item_1, parent, false);

            vh = new TextViewHolder(v);
        } else {
            View v = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.progress_item, parent, false);

            vh = new ProgressViewHolder(v);
        }
        return vh;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (holder instanceof TextViewHolder) {
            ((TextViewHolder) holder).mTextView.setText(mDataset.get(position).toString());
        } else {
            ((ProgressViewHolder) holder).progressBar.setIndeterminate(true);
        }
    }

    public void setLoaded() {
        loading = false;
    }

    @Override
    public int getItemCount() {
        return mDataset.size();
    }

    public void setOnLoadMoreListener(OnLoadMoreListener onLoadMoreListener) {
        this.onLoadMoreListener = onLoadMoreListener;
    }

    public interface OnLoadMoreListener {
        void onLoadMore();
    }

    public static class TextViewHolder extends RecyclerView.ViewHolder {
        public TextView mTextView;

        public TextViewHolder(View v) {
            super(v);
            mTextView = (TextView) v.findViewById(android.R.id.text1);
        }
    }

    public static class ProgressViewHolder extends RecyclerView.ViewHolder {
        public ProgressBar progressBar;

        public ProgressViewHolder(View v) {
            super(v);
            progressBar = (ProgressBar) v.findViewById(R.id.progressBar);
        }
    }
}

  • 在 Activity 类中更改代码

  • Change code in Activity class

    mAdapter = new MyAdapter<String>(myDataset, mRecyclerView);
    mRecyclerView.setAdapter(mAdapter);
    
    mAdapter.setOnLoadMoreListener(new MyAdapter.OnLoadMoreListener() {
        @Override
        public void onLoadMore() {
            //add progress item
            myDataset.add(null);
            mAdapter.notifyItemInserted(myDataset.size() - 1);
    
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    //remove progress item
                    myDataset.remove(myDataset.size() - 1);
                    mAdapter.notifyItemRemoved(myDataset.size());
                    //add items one by one
                    for (int i = 0; i < 15; i++) {
                        myDataset.add("Item" + (myDataset.size() + 1));
                        mAdapter.notifyItemInserted(myDataset.size());
                    }
                    mAdapter.setLoaded();
                    //or you can add all at once but do not forget to call mAdapter.notifyDataSetChanged();
                }
            }, 2000);
            System.out.println("load");
        }
    });
    

  • 其余保持不变,如果这对您有用,请告诉我.

    The rest remains unchanged, let me know if this works for you.

    这篇关于使用底部的 ProgressBar 将项目添加到 Endless Scroll RecyclerView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

    09-05 12:26