如何使用RecyclerView实现无限滚动? [英] How to implement Infinite Scrolling with RecyclerView?

查看:158
本文介绍了如何使用RecyclerView实现无限滚动?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个回收站,里面有卡片视图,我可以从REST服务中获取信息,我正在尝试实现无休止的滚动,假设用户每次向下滚动直到没有任何滚动时,都会看到10张卡片视图要显示更多卡片视图,我该如何实现?

I have a recycler and inside of it there are cardviews where I fetch information from a REST service, I'm trying to implement an endless scroll, It's supposed that user will see 10 cardviews every time he scrolls down until there are no more cardviews to show, How can I achieve that?

我看过几个例子,但是没有一个例子能真正帮助我.我什至不知道需要在adapter.class或Fragment.class中放入什么,因为我不知道如何实现,如果有人能告诉我实现无限滚动的正确方法,那将是很好的我的代码...

I've seen a few examples but none of them really helped me about how to do it. I don't even know what I need to put in adapter.class or in my Fragment.class because I don't understand how to implement that, it would be great if someone could tell me the correct way to implement the infinite scroll in my code...

谢谢.

MainAdapter.class

public class MainAdapter extends RecyclerView.Adapter<MainAdapter.ViewHolder> implements View.OnClickListener
{
    private ArrayList<Business> businessList;
    private Activity activity;
    private int layoutMolde,idb;

    public MainAdapter(Activity activity, ArrayList<Business> list, int layout) 
    {
        this.activity = activity;
        this.businessList = list;
        layoutMolde = layout;
    }

    @Override
    public MainAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) 
    {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.main_row, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) 
    {
        holder.mTitle.setText(businessList.get(position).getBusiness_name());
        holder.number_rating.setText(businessList.get(position).getRating().toString());
        Glide.with(activity).load(businessList.get(position).getLogo_url_string()).into(holder.mImg);
    }

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

    @Override
    public void onClick(View v) 
    {

    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        public TextView mTitle;
        public ImageView mImg;
        public ImageView logo;
        public RatingBar main_rating;
        public TextView number_rating;

        public ViewHolder( View itemView) 
        {
            super(itemView);
            mTitle = (TextView) itemView.findViewById(R.id.nom_business_main);
            number_rating = (TextView) itemView.findViewById(R.id.number_rating);
            mImg = (ImageView) itemView.findViewById(R.id.img_main);
            main_rating=(RatingBar) itemView.findViewById(R.id.rating_main);
            main_rating.setRating((float)1);
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v)
                {

                    Intent in = new Intent(v.getContext(), BusinessPremium.class);
                    int position = getAdapterPosition();
                    idb = businessList.get(position).getId();
                    in.putExtra("no", idb);
                    v.getContext().startActivity(in);
                }
            });
        }
    }
}

FeedsFragment.class

    public class FeedsFragment extends Fragment
    {

        private ArrayList<Business> arrayBusiness,arrayBasics;
        private Gson gson;

        private static final Type BUSINESS_TYPE = new TypeToken<ArrayList<Business>>() {}.getType();
        private RecyclerView.LayoutManager mLayoutManager;

        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
        {
            View android = inflater.inflate(R.layout.fragment_feeds, container, false);

            if (!internetConnectionCheck(FeedsFragment.this.getActivity())) 
            {
                Toast.makeText(getApplicationContext(), "Error de Conexión", Toast.LENGTH_LONG).show();
            }

            new RequestBase(getActivity()) {

                @Override
                public JsonObject onHttpOk(JsonObject response) throws JSONException {

                    JsonObject objeto, pagination_details = null, details, premium_img;
                    JsonArray data;

                    if (getActivity() == null)
                        return response;

                    if (response.get("pagination") == null) 
                    {
                        objeto = response;

                    } else {
                        objeto = response;
                        pagination_details = response.get("pagination").getAsJsonObject();
                        data = objeto.get("data").getAsJsonArray();
                        gson = new Gson();
                        arrayBusiness = gson.fromJson(data, BUSINESS_TYPE);
                        Log.d("size", String.valueOf(arrayBusiness.size()));
                        FeedsFragment.this.getActivity().runOnUiThread(new Runnable()
                        {
                            @Override
                            public void run() 
                            {

                                RecyclerView recycler = (RecyclerView) FeedsFragment.this.getActivity().findViewById(R.id.recycler_main);
                                MainAdapter adapter = new MainAdapter(getActivity(), arrayBusiness, R.layout.main_row);

                                recycler.setNestedScrollingEnabled(false);
                                mLayoutManager = new GridLayoutManager(FeedsFragment.this.getActivity(), 2);
                                recycler.setLayoutManager(mLayoutManager);
                                recycler.setAdapter(adapter);

                                GifTextView loading = (GifTextView)FeedsFragment.this.getActivity().findViewById(R.id.loading);
                                TextView loadingText = (TextView)FeedsFragment.this.getActivity().findViewById(R.id.loadingText);
                                loading.setVisibility(View.GONE);
                                loadingText.setVisibility(View.GONE);

                            }
                        });
                    }
                    if (pagination_details.isJsonNull()) {
                        Log.d("Paginacion", pagination_details.toString());
                    }
                    return objeto;
                }

                @Override
                public void onHttpCreate(JsonObject response) throws JSONException 
                {

                }

                @Override
                public void onHttpUnprocessableEntity(JsonObject response) throws JSONException 
                {
                    this.cancel(true);
                    final String error = response.get("errors").toString();
                    getActivity().runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(getActivity().getApplicationContext(), error, Toast.LENGTH_LONG).show();
                        }
                    });
                }
            }.execute("businesses/premiums", "GET");

            return android;
        }
}

推荐答案

编写 RecyclerView.Adapter ,无论如何,您都需要提供getItemCount方法来返回正确数量的项目(可能很大). RecyclerView将主动调用此适配器的onBindViewHolder(holder,position)方法.您所需要做的就是提供与该职位相关的数据检索功能.如果您的列表小于screen,略大于screen或Integer.MAX_VALUE大小,则没有任何区别. RecyclerView将注意不要获取/分配过多的额外项目.

When writing RecyclerView.Adapter, you anyway need to provide the getItemCount method that returns the correct number of items (may be large). RecyclerView will call on its own initiative the onBindViewHolder(holder, position) method of this adapter. All you need is to provide functionality of retrieving data, relevant to this position. There is no difference at all, if your list is smaller than screen, slightly larger than screen or Integer.MAX_VALUE size. RecyclerView will take care not to fetch/allocate too much extra items.

不是 需要实现滚动侦听器或以其他方式显式处理滚动.

You do not need to implement scroll listeners or otherwise explicitly handle the scrolling.

唯一棘手的部分是您可能需要采取长时间的操作(例如服务器调用)才能获得一些物品.然后,只需在第一次调用时返回未初始化的holder(空视图),然后开始在后台线程中获取所需的行.拥有它后,请调用notifyDataSetChangednotifyItemRangeChanged,然后RecyclerView会小心地进行自我更新.

The only tricky part is that you may need to take a long action like server call to get some items. Then just return uninitialized holder (empty view) on the first invocation and start fetching the needed row in the background thread. When you have it, call notifyDataSetChanged or notifyItemRangeChanged, and RecyclerView will take care to update itself.

出于性能方面的考虑,我强烈建议以固定大小的块更新内容,而不是每显示一行发送单独的服务器请求.对于某些公共服务器(例如Google图书),这显然是一项要求,因为它们具有每个请求的配额限制.

For performance reasons I would strongly recommend to update content in chunks of the fixed size rather than sending individual server request per every row displayed. For some public servers like Google Books this is clearly a requirement, as they have quota limits per request.

如果您需要查看有关如何实现的完整源代码,请使用

If you need to view the full source code on how this possibly could be implemented, there is an open source project here in GitHub.

这篇关于如何使用RecyclerView实现无限滚动?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆