android-从导航栏替换ViewPager中的片段

android-从导航栏替换ViewPager中的片段,android,android-fragments,android-viewpager,android-cardview,fragmentmanager,Android,Android Fragments,Android Viewpager,Android Cardview,Fragmentmanager,我正在开发一个Android应用程序,可以查看曲棍球比赛的结果。 我使用带有自定义FragmentPagerAdapter的ViewPager来显示三个片段,使用带有ExpandableListView的NavigationDrawer来显示锦标赛。 当我点击ExpandableListViewchildrens时,我想用所选锦标赛的数据更新这三个片段 我在NavigationDrawer中设置了一个OnchildClickListener,其中我指示了一个FragmentManager,并调用

我正在开发一个Android应用程序,可以查看曲棍球比赛的结果。 我使用带有自定义
FragmentPagerAdapter
ViewPager
来显示三个片段,使用带有
ExpandableListView
NavigationDrawer
来显示锦标赛。 当我点击
ExpandableListView
childrens时,我想用所选锦标赛的数据更新这三个片段

我在
NavigationDrawer
中设置了一个
OnchildClickListener
,其中我指示了一个
FragmentManager
,并调用了
replace()
方法。但它只是返回一个空白屏幕

我搜索了每个论坛,尝试了不同的解决方案,但没有一个是有效的 当我使用
ft.add()
而不是
ft.replace()
并使用
SwipeRefreshLayout
刷新页面时,我得到了正确的结果,但我不想手动刷新页面。 我还试图用
FragmentStatePagerAdapter
替换
FragmentPagerAdapter
,但没有任何改变

导航抽屉碎片
我将向您展示的是一种非常基本的更新
ViewPager
片段的方法,每次数据更改时都用新实例替换现有片段

这是公式:

  • 允许
    FragmentPagerAdapter
    获取一些更新的数据。在您的例子中,有一个名为“key”的int值,当用户从导航抽屉中选择一个项目时,该值会更新。我们将在您的
    FragmentPagerAdapter
    上放置一个方法,该方法将接受一个键值参数并开始更新
  • FragmentPagerAdapter
    上执行
    getItemPosition()
    以返回
    POSITION\u NONE
    。这将告诉
    ViewPager
    当前片段已过期,需要用另一个片段替换
  • 在适配器的
    getItem()
    方法中,在实例化新片段时使用当前键值。(您已经拥有此部件。)
以下是我对代码更改的建议:

  • 修改您的
    活动
    ,以便有一个对
    FragmentPagerAdapter
    实例的引用

    private MyFragmentPagerAdapter mAdapter;
    
  • 在您的
    活动中
    ,确保您的
    查看页面
    已使用您的
    FragmentPagerAdapter
    设置。(您没有发布您的
    活动
    代码,因此请确保您没有错过此内容。)这可能会发生在
    onCreate()

  • 将方法添加到您的
    活动中
    以接受来自导航抽屉的键值并将其传递到适配器(我们将在一分钟内处理适配器):

  • 从导航抽屉中删除此
    FragmentTransaction
    代码
    onChildClick()

    您的
    MyFragmentPagerAdapter
    将为您执行所有这些片段管理。因此,将该代码替换为:

    ((MainActivity) getActivity()).select(key);
    
    (我不知道你的活动叫什么,所以我只使用了
    MainActivity
    作为例子。)

  • 覆盖并实现
    FragmentPagerAdapter
    上的
    getItemPosition()
    ,使其始终返回
    POSITION\u NONE

    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }
    
    必须重写此方法,因为基类方法只返回
    POSITION\u UNCHANGED
    ,这将导致永远不会调用
    getItem()

  • 最后,在
    FragmentPagerAdapter
    上添加获取键值的方法。您已经有一个键的变量,因此可以使用该变量存储值:

    public void setKey(int key) {
        idcampionato = key;
        notifyDataSetChanged();
    }
    
  • 下面是事件的顺序:

    • 用户从导航抽屉中选择项目
    • onChildClick()
    • select()
      调用适配器上的
      setKey()
    • 适配器存储键值并调用notifyDataSetChanged()
    • ViewPager
      注意到适配器已更改,并通过调用适配器的
      getCount()
      来查看片段数是否已更改
    • ViewPager
      在每个页面位置调用
      getItemPosition()
      <返回code>POSITION\u NONE
      ,它告诉
      ViewPager
      需要删除该页面上的片段并用新片段替换
    • ViewPager
      然后在每个页面位置调用
      getItem()
      。这将调用片段的
      newInstance
      方法。由于您的
      idcampionato
      值已更新,因此将使用新键创建片段
    • ViewPager
      显示带有更新数据的新片段

    这并不像我最初建议的那样优雅,即只创建一次片段,然后在片段上有一个自定义方法来更新键和刷新片段视图。但是这种方法需要对代码进行更多的更改,所以我决定采用更简单的解决方案。

    对不起,我不明白这一点……我可以在哪里保存片段的引用以及如何保存?非常感谢。告诉你,发布你的
    PagerAdapter
    子类,我会更新我的答案。更新我的答案;抱歉花了这么长时间。。。我为您详细介绍了一个更简单的解决方案。干杯,非常感谢你!您的代码完全可以工作,但是我添加了一个事务来删除前面的片段以使其工作。另外,无论我点击什么,它都显示了相同的片段。嗯,这很奇怪。。。
    FragmentPagerAdapter
    应该为您处理所有片段事务。。。我很想看看你的更新代码。如果您愿意,请在问题中发布您的最新代码。但是,嘿,如果你对结果感到满意,并且你只想结束这一天,我很乐意。:)
    mAdapter = new MyFragmentPagerAdapter();
    ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
    
    public void select(int key) {
        mAdapter.setKey(key);
    }
    
                //gets Fragment Manager
                FragmentManager fragmentManager = getFragmentManager();
                //starts the transaction
                android.support.v4.app.FragmentTransaction ft = fragmentManager.beginTransaction();
                ft.replace(R.id.viewpager, PagePartite.newInstance(key));   //first page
                ft.replace(R.id.viewpager, PageClassifica.newInstance(key));    //second page
                ft.replace(R.id.viewpager, PageStatistiche.newInstance(key));
                ft.addToBackStack(null);
                ft.commit();
    
    ((MainActivity) getActivity()).select(key);
    
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }
    
    public void setKey(int key) {
        idcampionato = key;
        notifyDataSetChanged();
    }