持久片段和查看器

Posted

技术标签:

【中文标题】持久片段和查看器【英文标题】:Persistant fragments and viewpager 【发布时间】:2017-05-13 19:40:53 【问题描述】:

我想在一个 android 应用程序中使用 3 个片段,我红色: Creating-and-Using-Fragments .但是我想使用viewpager来滑动和显示片段,如下所述: ViewPager-with-FragmentPagerAdapter .但是这段代码还是Android Studio Example的默认代码,使用newInstance来创建实例,每次需要的时候,不需要的时候就销毁。

// Returns the fragment to display for that page
    @Override
    public Fragment getItem(int position) 
        switch (position) 
        case 0: // Fragment # 0 - This will show FirstFragment
            return FirstFragment.newInstance(0, "Page # 1");
        case 1: // Fragment # 0 - This will show FirstFragment different title
            return FirstFragment.newInstance(1, "Page # 2");
        case 2: // Fragment # 1 - This will show SecondFragment
            return SecondFragment.newInstance(2, "Page # 3");
        default:
            return null;
        
    

但我想一劳永逸地创建:

        // Within an activity

private FragmentA fragmentA;
private FragmentB fragmentB;
private FragmentC fragmentC;

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    if (savedInstanceState == null) 
        fragmentA = FragmentA.newInstance("foo");
        fragmentB = FragmentB.newInstance("bar");
        fragmentC = FragmentC.newInstance("baz");
    

并且只隐藏/显示它们,如示例所示:

    // ...onCreate stays the same

// Replace the switch method
protected void displayFragmentA() 
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    if (fragmentA.isAdded())  // if the fragment is already in container
        ft.show(fragmentA);
     else  // fragment needs to be added to frame container
        ft.add(R.id.flContainer, fragmentA, "A");
    
    // Hide fragment B
    if (fragmentB.isAdded())  ft.hide(fragmentB); 
    // Hide fragment C
    if (fragmentC.isAdded())  ft.hide(fragmentC); 
    // Commit changes
    ft.commit();

但是如何使用 FragmentPagerAdapter 做到这一点 public Fragment getItem(int position) 不再是那样

还有,如何访问数据

 public double [][] tableaux;

那是在一个 Fragment 的 MainActivity 中。 如果我将刚刚在 MainActivity onCreate 中创建的 Fragment 的指针分配到 MainActivity.tableaux 上,则数据将是持久的

【问题讨论】:

【参考方案1】:

您可以在getItem 方法中返回预初始化的片段。

@Override
public Fragment getItem(int position) 
    switch (position) 
    case 0: return fragmentA;
    case 1: return fragmentB;
    case 2: return fragmentC;
    default: return null;

更新: @Alok 是对的。 Activity 中不应包含 fragment references。我建议不要使用setOffscreenPageLimit 增加屏幕外页面限制,而应考虑使用public void onSaveInstanceState(Bundle)savedInstanceStatepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 参数保存和恢复fragment 状态。

【讨论】:

谁向我保证,如果片段管理器不再需要它们,它将不会从内存中卸载它们。它们不会被重新创建,因为创建只会在 MainActivity.onCreate 中完成一次 您已将它们创建为全局变量,它们将仅通过 Activity 从内存中删除,否则它们将在内存中。 @Ravi Sisodia,它一直在工作,直到我放了 3 个以上的片段(6 个)。然后,当从第 4 次滑动到第 3 次或第 5 次时,应用程序崩溃 @Ravi Sisodia 可能与仅保存在容器中的 3 个片段有关。所以我升级到 mViewPager.setOffscreenPageLimit(6);但没办法它仍然崩溃。我可以更改 viewpager 或 SectionsPagerAdapter 以使其仅隐藏/显示而不删除(或关闭)片段吗? 我以使用新操作创建所有片段结束。结果片段=新结果片段();并将指针返回到 getItem 中的 6 个片段。工作正常,直到我倾斜屏幕,当方向改变时,手指滑动以获得以下片段,应用程序崩溃。为什么?【参考方案2】:

@Lotfi 您不需要将片段保存在活动中,它很容易泄漏。 您还可以为每个片段分配 id,稍后当您需要重用该片段时,您可以要求片段管理器通过传递 ie 返回片段。通过在 getItem() 中调用片段管理器方法 findFragmentByID()

【讨论】:

我的片段会处理一个图表,所以我每次都会浪费太多时间来回馈它 你不需要重新创建它,它只由片段管理器管理,让它知道你想要显示的片段,如果它已经在堆栈中,那么它将使用相同的片段。 是的,我知道,但如果它不再在容器中,则需要重新创建它并花费时间,请参阅我的第一个链接“Creating-and-Using-Fragments”中的“Fragment Hiding vs Replace” “ 更多。所以我需要保留在内存中并在它们之间交换 它将保留在内存中但不附加到容器中,因此可以毫无问题地重复使用。 请考虑这个答案:***.com/questions/13149446/…

以上是关于持久片段和查看器的主要内容,如果未能解决你的问题,请参考以下文章

14.VisualVM使用详解15.VisualVM堆查看器使用的内存不足19.class文件--文件结构--魔数20.文件结构--常量池21.文件结构访问标志(2个字节)22.类加载机制概(代码片段

行历史查看器 - Git

具有 IntelliJ 集成的日志查看器 [关闭]

Three.js 中的自定义纹理着色器

Lync Server 2013 持久聊天服务器通道关闭

什么是事件查看器