【问题标题】:Android RecyclerView adding paginationAndroid RecyclerView 添加分页
【发布时间】:2018-02-05 03:05:51
【问题描述】:

我为我的应用程序创建了一个 RecyclerView 并试图找到一种方法来停止巨大的请求,我希望通过进度条获得 10 x 10 的结果。我的服务器将在每次向下滚动到最后一项时以 10 x 10 的方式发送结果。

    public class ProfileActivityFriendsList extends AppCompatActivity {
        String[] names={"Ander Herera","David De Gea","Michael Carrick","Juan Mata","Diego Costa","Oscar"};
        String[] positions={"Midfielder","GoalKeeper", "Midfielder","Playmaker","Striker","Playmaker"};
        String[] urls={"Midfielder","GoalKeeper", "Midfielder","Playmaker","Striker","Playmaker"};
        int[] images = {R.mipmap.ic_launcher,R.mipmap.ic_launcher, R.mipmap.ic_launcher,R.mipmap.ic_launcher,R.mipmap.ic_launcher,R.mipmap.ic_launcher};

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_profile_friends_list);

            Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
            setSupportActionBar(toolbar);

            //GET RECYCLER
            RecyclerView rv = (RecyclerView) findViewById(R.id.myRecycler);
            //SET LAYOUT
            rv.setLayoutManager(new LinearLayoutManager(this));
            rv.setItemAnimator(new DefaultItemAnimator());
            //ADAPTER
            MyAdapter adapter = new MyAdapter(this, names, positions, urls, images);
            rv.setAdapter(adapter);
        }
} 

这是我的适配器类。

public class MyAdapter extends RecyclerView.Adapter<MyHolder> {
    Context c;
    String[] names;
    String[] positions;
    String[] urls;
    int[] img;

    public MyAdapter(Context ctx, String[] names, String[] positions,String[] urls, int[] images){
        this.c=ctx;
        this.names = names;
        this.positions = positions;
        this.img = images;
        this.urls = urls;
    }
    @Override
    public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.friend_list_model,null);

        MyHolder holder = new MyHolder(v);
        return holder;
    }

    @Override
    public void onBindViewHolder(MyHolder holder, final int position) {
        holder.imageView.setImageResource(img[position]);
        holder.name.setText(names[position]);
        holder.desc.setText(positions[position]);

        holder.serItemClickListener(new ItemClickListener() {
            @Override
            public void onItemClick(View v, int pos) {
                Snackbar.make(v,positions[position]+" "+positions[position],Snackbar.LENGTH_LONG).show();
            }
        });
    }

    @Override
    public int getItemCount() {
        return names.length;
    }
}

这是持有人。

public class MyHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
    CircleImageView imageView;
    TextView name;
    TextView desc;
    ItemClickListener itemClickListener;
    public MyHolder(View itemView) {
        super(itemView);

        imageView = (CircleImageView) itemView.findViewById(R.id.circleImageView1);
        name = (TextView) itemView.findViewById(R.id.textName);
        desc = (TextView) itemView.findViewById(R.id.textDesc);
        itemView.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        this.itemClickListener.onItemClick(v,getLayoutPosition());
    }
    public void serItemClickListener(ItemClickListener ic){
        this.itemClickListener = ic;
    }
}

看了很多教程,找不到明确的解决方案,我认为有一些方法可以做到,但我不知道我的代码是否可以添加它?

【问题讨论】:

    标签: android android-recyclerview


    【解决方案1】:

    我们所做的是使用ReyclerView.OnScrollListener。假设您使用的是LinearLayoutManager,您可以检查当前显示的项目与总计数,以确定您何时到达最后一个项目,然后请求下一页。您还需要提前进行一些额外的逻辑检查,以防止“垃圾邮件”,因为滚动甚至发生了很多。

    例如:

    recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            if (!hasMoreContent()) {
                return;
            }
    
            if (currentlyLoadingInitialRequest()) {
                return;
            }
    
            if (alreadyLoadingNextPage()) {
                return;
            }
    
            if (isInErrorState()) {
                return;
            }
    
            LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
            int total = layoutManager.getItemCount();
            int currentLastItem = layoutManger.findLastVisibleItemPosition();
            if (currentLastItem == total - 1) {
                requestNextPage();
            }
        });
    

    【讨论】:

    • 这是一个有用的技巧,谢谢
    【解决方案2】:

    https://github.com/kunal-mahajan/PaginationAdeptor

    我已经实现了分页组件/小部件,实现起来非常简单。不需要xml,只需要扩展类。上面的 url 中提供了带有计时器任务和虚拟数据的示例。在主要活动中,您可以更改“final int totalRecords”中可用于测试目的的数据数量;如果有任何问题将回答您的问题。 谢谢 库纳尔

    【讨论】:

    • 对我的工作非常好,非常感谢 kunal!我发现它是解决复杂问题的有趣方法。如果请求 cout 没有填满屏幕,它也可以工作,它会自动加载新请求。
    • 惊人的代码先生。您已经通过自动分页简化了任何水平或垂直的列表加载屏幕,唯一的要求是为任何屏幕创建适配器类。喜欢这个代码先生。谢谢!
    • 非常感谢先生,节省了一天多的工作量。
    【解决方案3】:

    你可以试试这个方法:

      mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener()
    {
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            if (dy > 0) //check for scroll down
            {
                visibleItemCount = mLayoutManager.getChildCount();
                totalItemCount = mLayoutManager.getItemCount();
                pastVisibleItems = mLayoutManager.findFirstVisibleItemPosition();
    
                if (loading) {
                    if ((visibleItemCount + pastVisibleItems) >= totalItemCount) {
                        loading = false;
                        if (adapter.countOfShowing < adapter.allChallenges.size()) {
                            Log.e("...", "Last Item Wow !");
                            adapter.increaseCountOfShowing();
                            adapter.notifyDataSetChanged();
                        }
                        loading = true;
                        //Do pagination.. i.e. fetch new data
                    }
                }
            }
        }
    });
    

    【讨论】:

    • 你能举一些关于adapter.countOfShowing、adapter.allChallenges.size()、adapter.increaseCountOfShowing()的例子吗?我需要如何实现它们?
    • 哦,是的,对不起。我只是在这里复制了我自己的代码。我在我的适配器 allItems 和 shownItems 中保留了 2 个数组(让我们这样称呼它们)。 increaseCountOfShowing() 只是增加showItemsSize 并用AllItems 元素填充它们。你清楚吗?
    • nop :D,我将尝试找到一种方法来理解 onScrolled 和适配器问题。感谢您的帮助!。
    • 我做了所有的部分,除了 countOfShowing 人。您是如何将 countOfShowing 设为 int 的?它的方法是什么?
    • 只有一个简单的方法可以将变量 countOfShowing 称为 increaseCountOfShowing() 例如增加 10。然后我用新的大小重新初始化显示项目数组并用 allItems 元素填充它
    猜你喜欢
    • 2014-12-14
    • 1970-01-01
    • 1970-01-01
    • 2018-08-16
    • 1970-01-01
    • 2015-09-23
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    相关资源
    最近更新 更多