【问题标题】:My fragments in viewpager tab dont refresh我在 viewpager 选项卡中的片段不刷新
【发布时间】:2013-01-24 05:56:59
【问题描述】:

我有 4 个标签的 viewpager .. 在每个标签中都有一个片段。 我的第一个选项卡是一个带有表单的片段(例如用户) 单击保存后,数据将插入数据库中。 我的第二个选项卡是另一个带有表单的片段,但它使用第一个选项卡中的数据(我从数据库中获取它)来填充微调器。 现在,在我从第一个选项卡成功插入数据后,在我的第二个选项卡中,微调器为空。因为我的数据库查询是在第二个片段的 onCreateView() 中实现的,所以它只在应用程序启动时调用一次,所以在 tab 1 和 tab2 之间切换不会启动 onCreateView() 甚至 onResume()。 对我来说有趣的是,如果我转到 tab4 然后返回 tab2,我的数据正确地在我的微调器中,所以以某种方式从我当前的选项卡上滑动两个选项卡刷新我的片段。 我的问题是当 onCreateView() 只被调用一次时,我怎样才能实现对我的片段的正确刷新?

编辑 我试图把 psykhi 建议的方法放在这样的地方:

    this.mViewPager.setOffscreenPageLimit(0);
    this.mViewPager.setAdapter(this.mPagerAdapter);
    this.mViewPager.setOnPageChangeListener(this);

但这对我不起作用。我错过了什么吗?

【问题讨论】:

    标签: android android-viewpager fragment


    【解决方案1】:

    我发现模拟“setOffscreenPageLimit(0)”行为的最佳方法是使用 OnPageChangeListener 并覆盖适配器中的 getItemPosition 方法。像这样的:

    在您的自定义寻呼机适配器中:

    @Override
    public int getItemPosition(Object object) {
         return POSITION_NONE;
    }
    

    然后在包含 ViewPager 的 Activity 中:

    final MyPagerAdapter adapter = new MyPagerAdapter();
    pager.setAdapter(adapter);
    pager.setOnPageChangeListener(new OnPageChangeListener() {
         @Override
         public void onPageSelected(int position) {
              ... anything you may need to do to handle pager state ...
              adapter.notifyDataSetChanged(); //this line will force all pages to be loaded fresh when changing between fragments
         }
    }
    

    这应该与将 OffscreenPageLimit 设置为 0 具有相同的效果。但是,此功能与 ViewPager 旨在提供的功能有些背道而驰。如果您尝试以这种方式实现 ViewPager,则可能值得重新评估您的布局,以确保 ViewPager 确实是您想要使用的。

    【讨论】:

    • @Virus 这就是为什么首先在 ViewPager 中引入页面缓存的原因 - 以消除滞后
    【解决方案2】:

    更新:有更好的方法,请看这里:Update ViewPager dynamically?


    删除此答案的内容,因为这是在ViewPager 中访问Fragments 的一种非常糟糕的方式,请参阅上面的链接以获得更好的方法。

    【讨论】:

    • 是的,这可以解决问题。我想知道setOffscreenPageLimit 方法以及为什么将两个标签滑开然后回到原来的标签,然后我的 onCreateView 才被再次调用。
    • setOffscreenPageLimit() 的默认值是 1。这意味着当前选项卡每一侧的 1 将被初始化/缓存。当您离开 2 个选项卡时,相关选项卡将被取消缓存/销毁。所以回来会再次启动它,这次一切都会正常。
    • 每次我滚动浏览它时应用程序都会崩溃并显示错误cast exception : package.fragment can not be casted to package.fragment$refreshlistener
    • 你好,它给出了 java.lang.ClassCastException: what to do...urgent
    • @Virus 使用这里提到的机制stackoverflow.com/questions/10849552/…
    【解决方案3】:

    这是因为您可以指定查看器将“保留在 RAM 中”的片段数(setOffScreenPageLimit () :我认为默认值为 1)。所以你的第二个片段不会重新加载。当您转到标签 3 或 4 时,您的 2 个第一个片段会被删除,然后在您返回时重新创建。

    要刷新您的片段,有很多方法可以做到:您可以在其中实现自己的侦听器接口来告诉它何时刷新,或者简单地调用您将实现的方法来更新您的内容。

    【讨论】:

      【解决方案4】:

      片段方法中的第一次覆盖

      @Override
      public void setUserVisibleHint(boolean isVisibleToUser) {
          super.setUserVisibleHint(isVisibleToUser);
          if(isVisibleToUser){
              actionView();//call the method to be refreshed
          }
          else{
              //no
          }
      
      }
      

      【讨论】:

        【解决方案5】:

        根据我的经验,ViewPagers 保持:

        • 您当前的标签
        • & 内存中的任一侧都有 1 个选项卡

        因此,当您在 1 和 2 之间切换时,引擎盖下不会发生任何事情 - 就像它们只是被隐藏/显示一样。

        但是当您导航到选项卡 4 时,选项卡 1 和 2 会被销毁(调用 onDestroy()),因此当您导航回其中任何一个时,它们会被重新创建(调用 onCreate())。

        正如psykhi 建议的那样,您可以将setOffScreenPageLimit() 设置为0,这样每次导航到它时都会创建每个片段。

        如果您有兴趣将其他页面保留在内存中以用于性能目的,他们的设计初衷是这样,您可以使用消息/事件发布系统从标签 1 发送消息到选项卡 2 告诉它在您在选项卡 1 上提交表单时更新。

        【讨论】:

        • 它的行为如此疯狂..对于初学者来说,有人会认为 android studio 很奇怪
        • 我在想复制和粘贴片段结构和修改会导致这个问题(因为它在 xml 文件中发生,你在一个地方重构 id 它会随处改变).. 所以我认为一些奇怪的链接可能在那里,但这是完全不同的......
        【解决方案6】:

        好吧,可能是一个迟到的回复,将来可能会帮助其他人,所以最近我在将数据从 db 提取到它曾经只在我点击第三个选项卡时才显示的选项卡时遇到了同样的问题。我尝试了上面提到的解决方案,但实际上没有工作.. 最终我遇到了Otto 这个库允许你在你的应用程序中进行通信..

        只要在你从数据库中获取数据的任何地方使用这个库到 yourAdapter.notifyDataSetChanged() ..

        这个视频对我帮助很大https://www.youtube.com/watch?v=lVqBmGK3VuA

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-09-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-12-24
          • 2012-04-16
          相关资源
          最近更新 更多