【问题标题】:ViewPager showing data wrong with RecyclerViewViewPager 使用 RecyclerView 显示数据错误
【发布时间】:2015-11-18 12:39:11
【问题描述】:

我正在尝试显示每年的假期(使用 volley 从 Web 服务获取)并且我使用 RecyclerView 来显示假期。以下是我的代码: 它总体上可以正常工作,但此代码中存在一些问题。 我不知道我在这里做错了什么?

public class ShowHolidaysPage extends AppCompatActivity implements ViewPager.OnPageChangeListener{ 
        private static final int PAGE_LEFT = 0;
        private static final int PAGE_MIDDLE = 1;
        private static final int PAGE_RIGHT = 2;
        HolidayFragment leftPage = null,middlePage = null,rightPage = null;
        List<HolidayFragment> fList = new ArrayList<HolidayFragment>();
        enter code here
        @Override
        protected void onCreate(Bundle savedInstanceState) {
           fList.add(HolidayFragment.newInstance("" + (year1 - 1), authToken,      deviceId,yearList));
            fList.add(HolidayFragment.newInstance("" + year1, authToken, deviceId,yearList));
            fList.add(HolidayFragment.newInstance("" + (year1 + 1), authToken, deviceId,yearList));
             leftPage = fList.get(PAGE_LEFT);
            middlePage = fList.get(PAGE_MIDDLE);
            rightPage = fList.get(PAGE_RIGHT);
            init();
            pageAdapter = new MyPageAdapter(getSupportFragmentManager(), fList);
            pager = (ViewPager)findViewById(R.id.holiday_pager);
            pager.setAdapter(pageAdapter);
            pager.setOnPageChangeListener(this);
            pager.setCurrentItem(1, false);
    }

    @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        }

        @Override
        public void onPageSelected(int position) {
            mSelectedPageIndex = position;
        }

        @Override
        public void onPageScrollStateChanged(int state) {
            if (state == ViewPager.SCROLL_STATE_IDLE) {

     final int oldLeftIndex = leftPage.getIndex();
                final int oldMiddleIndex = middlePage.getIndex();
                final int oldRightIndex = rightPage.getIndex();

                if (mSelectedPageIndex == PAGE_LEFT) {
                    currentYear.add(Calendar.YEAR, -1);
                    Calendar prevYear = Calendar.getInstance();
                    prevYear.setTime(currentYear.getTime());
                    prevYear.add(Calendar.YEAR, -1);
                    Calendar nextYear = Calendar.getInstance();
                    nextYear.setTime(currentYear.getTime());
                    nextYear.add(Calendar.YEAR, 1);
                    leftPage.setIndex(oldLeftIndex - 1, prevYear);
                    middlePage.setIndex(oldLeftIndex, currentYear);
                    rightPage.setIndex(oldMiddleIndex, nextYear);
                } 

    else if (mSelectedPageIndex == PAGE_RIGHT) {
                    currentYear.add(Calendar.YEAR, 1);
                    Calendar prevYear = Calendar.getInstance();
                    prevYear.setTime(currentYear.getTime());
                    prevYear.add(Calendar.YEAR, -1);
                    Calendar nextYear = Calendar.getInstance();
                    nextYear.setTime(currentYear.getTime());
                    nextYear.add(Calendar.YEAR, 1);
                    leftPage.setIndex(oldMiddleIndex, prevYear);
                    middlePage.setIndex(oldRightIndex, currentYear);
                    rightPage.setIndex(oldRightIndex + 1, nextYear);
                }
     pager.setCurrentItem(1, false);
    }
    }

     class MyPageAdapter extends FragmentStatePagerAdapter  {
            private List<HolidayFragment> fragments;
            public MyPageAdapter(FragmentManager fm, List<HolidayFragment> fragments) {
                super(fm);
                this.fragments = fragments;
            }
            @Override
            public Fragment getItem(int position) {
                return this.fragments.get(position);
            }
            @Override
            public int getCount() {
                return this.fragments.size();
            }
        }
    }
    this method is in holiday fragment:
       public void setIndex(int index,Calendar year1) {
            this.index = index;
            if(year1 != null) {
                year = ""+year1.get(Calendar.YEAR);
                if(year.equals(""+year1.get(Calendar.YEAR))) {
                    String year = "" + year1.get(Calendar.YEAR);
                    yearView.setText(year);
                    if(networkCall.getRequestQueue()!= null) {
                        networkCall.getRequestQueue().cancelAll(getTag());
                    }
                    getHolidays(authtoken, deviceId, yearView.getText().toString());
                }
            }
        }

    public void getHolidays(String authToken, String deviceID, final String year) {
            if(recyclerView != null) {
                if (recyclerView.getVisibility() == View.VISIBLE) {
                    recyclerView.setVisibility(View.GONE);
                }
            }
            if(holidayNotAvailable != null) {
                if (holidayNotAvailable.getVisibility() == View.VISIBLE) {
                    holidayNotAvailable.setVisibility(View.GONE);
                }
            }
            if(yearList==null){
                yearList=new ArrayList<Integer>();
            }

            if(!yearList.contains(Integer.parseInt(year))) {
                progressbar.setVisibility(View.VISIBLE);
                networkCall = NetworkCall.getInstance(getActivity().getApplicationContext());
                String url = url;
                url += "&year=" + year;
                JsonObjectRequest jsonObject = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject jsonObject) {
                        yearList.add(Integer.parseInt(year));
                        try {
                            Map<String, String> holidaysMap = new Gson().fromJson(jsonObject + "", new TypeToken<SortedMap<String, String>>() {
                            }.getType());
                            progressbar.setVisibility(View.GONE);
                            if (holidaysMap.size() != 0) {
                                if (holidayNotAvailable.getVisibility() == View.VISIBLE) {
                                    holidayNotAvailable.setVisibility(View.GONE);
                                }
                                LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity().getApplicationContext());
                                recyclerView.setVisibility(View.VISIBLE);
                                recyclerView.setLayoutManager(layoutManager);
                                adapter = new HolidayAdapter(holidaysMap, year);
                                recyclerView.setAdapter(adapter);
                            } else {
                                progressbar.setVisibility(View.GONE);
                                recyclerView.setVisibility(View.GONE);
                                holidayNotAvailable.setVisibility(View.VISIBLE);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }, new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError volleyError) {
                        String msg = "";
                        if (volleyError instanceof TimeoutError || volleyError instanceof NoConnectionError) {
                            msg = "Time out Error! Please try again later";
                        } else if (volleyError instanceof AuthFailureError) {
                            startActivity(new Intent(getActivity().getApplicationContext(), IntroActivity.class));
                        } else if (volleyError instanceof ServerError) {
                            msg = "Server Error! Please try again later";
                        } else if (volleyError instanceof NetworkError) {
                            msg = "Network Error! Please try again later";
                        } else if (volleyError instanceof ParseError) {
                            msg = "Parser Error! Please try again later";
                        }
                        if (!EwUtils.isNullString(msg)) {
                            if (getActivity() != null) {
                                Toast.makeText(getActivity().getApplicationContext(), msg, Toast.LENGTH_SHORT);
                            }
                        }
                    }
                });
                networkCall.addToRequestQueue(jsonObject);
            }
}

它在向左或向右滑动时显示页面正确,但现在存在以下两个问题:

  1. 一次三个页面表单,所以当我们向左或向右滑动时,它会再次调用 get holiday 方法,该方法在创建视图时创建视图,所以我无法知道它为什么要重新创建页面。
  2. 当我们快速滑动时,它显示数据错误。它似乎将另一个请求的数据放在另一个片段中。

我已经尝试过使用 pager.setOffscreenPageLimit(1);但在空闲状态时不起作用并重新创建片段。

我不知道我在这里做错了什么。所以请指导我。

【问题讨论】:

    标签: android android-viewpager android-recyclerview android-volley


    【解决方案1】:

    默认情况下,您的 ViewPager 保留活动(当前)片段的左一页和右一页。

    也就是说,当您转到第三个时,第一个被销毁,第四个被创建为缓存,以提供更好的用户体验。

    您可以通过调用 ViewPager setOffscreenPageLimit 的方法更改您的限制

    关于您的错误数据:我建议您将不同实例中的逻辑与此类分开。问题是请求是异步发出的,因此您在返回响应之前更改页面,并且调用同一段代码似乎很混乱。

    希望对你有帮助

    【讨论】:

    • 感谢 Juan,我尝试在 setOffscreenPageLimit() 中设置限制 2 和 3,但它不起作用。我在这里做错了吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多