使用AsyncTask进行RecyclerView分页制作重复页面? [英] RecyclerView Pagination Using AsyncTask Making Duplicate Pages?

查看:70
本文介绍了使用AsyncTask进行RecyclerView分页制作重复页面?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个图库应用程序,该应用程序正在解析Reddit API并用图像填充recyclerview列表.每页包含该subreddit中的25张图片.但是,此代码正在进行重复的数据调用,当您滚动2或3次才能将相同的页面放入图库时,它们才会到达下一页.我将如何解决此问题?

I have a gallery application that is parsing the Reddit API and populating a recyclerview list with images. Each page contains 25 pictures from that subreddit. But this code is making duplicate data calls which puts the same pages in the gallery when you scroll 2 or 3 times before it get the next page. How would I be able to fix this problem?

 public class DesktopGalleryFragment extends Fragment{
    private int count;
    private RecyclerView mDesktopRecyclerView;
    private List<DesktopItems> mList = new ArrayList<>();
    private String after, nullString;
    private Parcelable recyclerViewState;

    public String getAfter(String s){
        return this.after = s;
    }

    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
        new FetchItemsTask().execute(nullString);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
        mDesktopRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener(){
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState){

                PhotoAdapter adapter = (PhotoAdapter) recyclerView.getAdapter();
                int lastPostion = adapter.getLastBoundPosition();
                GridLayoutManager layoutManager = (GridLayoutManager) recyclerView.getLayoutManager();
                int loadBufferPosition = 1;
                if (lastPostion >= adapter.getItemCount() - layoutManager.getSpanCount() - loadBufferPosition){
                    new FetchItemsTask().execute(after);
                }
            }
        });

        return v;
    }

    private class FetchItemsTask extends AsyncTask<String, Void, List<DesktopItems>>{
        @Override
        protected List<DesktopItems> doInBackground(String... params){
            return new RedditParser().fetchItems(params[0]);
        }

        @Override
        protected void onPostExecute(List<DesktopItems> items){
            if (count > 1){
                getAfter(DesktopItems.getAfter());
                mList.addAll(items);
                mDesktopRecyclerView.getAdapter().notifyDataSetChanged();
            } else{
                mList = items;
                recyclerViewState = mDesktopRecyclerView.getLayoutManager().onSaveInstanceState();
                mDesktopRecyclerView.getLayoutManager().onRestoreInstanceState(recyclerViewState);
                setupAdapter();
            }
            count++;
        }
    }
}

RedditParser.java

RedditParser.java

public List<DesktopItems> fetchItems(String after)
{
    List<DesktopItems> items = new ArrayList<>();
    int count = 0;
    int counter = count + 25;

    try
    {
        String url = Uri.parse("https://www.reddit.com/r/battlestations/hot.json")
                .buildUpon()
                .appendQueryParameter("after", after)
                .build()
                .toString();
        String jsonString = getUrlString(url);
        Log.i(TAG, "Received JSON: " + jsonString);
        JSONObject jsonBody = new JSONObject(jsonString);
        parseItems(items, jsonBody);
    return items;
}

推荐答案

由于onScrollStateChanged的工作方式,您正在重叠调用FetchItemsTask.如果向上滑动并让一切安定下来,则以下是onScrollStateChanged的调用方式:

You are getting overlapping calls to FetchItemsTask due to how onScrollStateChanged works. If you swipe up and let things settle, here is how onScrollStateChanged is invoked:

onScrollStateChanged:SCROLL_STATE_DRAGGING
onScrollStateChanged:SCROLL_STATE_SETTLING
onScrollStateChanged:SCROLL_STATE_IDLE

onScrollStateChanged: SCROLL_STATE_DRAGGING
onScrollStateChanged: SCROLL_STATE_SETTLING
onScrollStateChanged: SCROLL_STATE_IDLE

这就是您所期望的.但是,如果您先向上滑动然后在视图稳定之前再次向上滑动,则会发生以下情况:

This is what you would expect. If, however, you swipe up and then swipe up again before the view settles, this is what happens:

onScrollStateChanged:SCROLL_STATE_DRAGGING
onScrollStateChanged:SCROLL_STATE_SETTLING
onScrollStateChanged:SCROLL_STATE_DRAGGING
onScrollStateChanged:SCROLL_STATE_SETTLING
onScrollStateChanged:SCROLL_STATE_IDLE

onScrollStateChanged: SCROLL_STATE_DRAGGING
onScrollStateChanged: SCROLL_STATE_SETTLING
onScrollStateChanged: SCROLL_STATE_DRAGGING
onScrollStateChanged: SCROLL_STATE_SETTLING
onScrollStateChanged: SCROLL_STATE_IDLE

乍一看,这似乎令人惊讶,但是如果您考虑一下,这是有道理的.

This may seem surprising at first, but it makes sense if you think about it.

您还没有对onScrollStateChanged中的newState做任何检查.

You are also not doing any checks for the newState in onScrollStateChanged.

如果您要实施无尽的RecyclerView,请尝试搜索无尽的recyclerview".网络上有很多不错的资源.

If you are trying to implement an endless RecyclerView try searching for "endless recyclerview". There are many good resources on the web.

这篇关于使用AsyncTask进行RecyclerView分页制作重复页面?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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