欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

一种FragmentStatePagerAdapter更新数据的方法

程序员文章站 2022-06-01 16:31:05
...

在listview中,如果我们要更新数据直接调用notifyDataSetChanged()即可,但是在Viewpager嵌套fragment时,导致直接调用并不会生效。具体原因可以参考这篇,作者分析的非常透彻,而且给出了FragmentPagerAdapter 更新数据的解决方案。

但是正如作者在文中所说的一样,少量页面应该选择使用FragmentPagerAdapter ,但是页面较多时,还是应该使用FragmentStatePagerAdapter,而在FragmentStatePagerAdapter中只能通过强制销毁页面并重建的方式更新数据么?

最近在做一个项目,viewpager的页面是不固定的,理论上可以是非常多的,这时候就要使用FragmentStatePagerAdapter来优化体验了,但是更新数据时,大多是只是更新一些页面上一些空间的显示,直接调用notifyDataSetChanged,重建页面有点太浪费了,于是我就想了一个简单的解决方案,在这里和大家分享一下,大家有更好的方法话可以提出来,共同学习。

基本思路就是在更新的时候,拿到当前页面以及前一个和后一个页面的fragment,然后调用fragment中我们的某些更新方法,进行页面的刷新。
这样就不用notifyDataSetChanged(),直接更新控件即可。

获取当前页面的fragment(在FragmentStatePagerAdapter中添加):

    @Override
    public void setPrimaryItem(ViewGroup container, int position, Object object) {
        currentFragment = (BaseFragment) object;
        super.setPrimaryItem(container, position, object);
    }

    public BaseFragment getCurrentFragment(){
        return currentFragment;
    }

同时在创建fragment时,将当前页面的位置作为参数保存进去:

    @Override
    public BaseFragment getItem(int position) {
        LogUtils.d("getItem"+position);
        return FragmentFactory.getInstance().createFragment(position);
    }

在Activity中刷新时:

private void refreshPage(){
        int currentPos = adapter.getCurrentFragment().getCurrentPosition();
        int previousPos = currentPos - 1;
        int nextPos = currentPos + 1;
        LogUtils.d("currentPos:"+currentPos+"  previousPos:"+previousPos+"  nextPos:"+nextPos);
        if(previousPos != -1){
            adapter.getItem(previousPos).refreshData();
        }

        adapter.getItem(currentPos).refreshData();

        if(nextPos <= adapter.getCount() - 1){
            adapter.getItem(nextPos).refreshData();
        }
    }

思路和方法都是很简单的,就是想办法获取到当前fragment实例,然后顺带刷新前一个和后一个页面(ViewPager会预加载这些页面)。当然,如果你认为就更新个数据,添加这么多代码很麻烦,直接修改getItemPosition():

@Override
    public int getItemPosition(Object object) {
        LogUtils.d("getItemPosition");
        return PagerAdapter.POSITION_NONE;
    }

在更新数据时,像listview一样直接调用notifyDataSetChanged()就可以了。但是,如果你是用的FragmentPagerAdapter ,就要谨慎一些了。