问题:
我目前遇到了一个问题,我的应用程序在第一次打开时试图加载太多的片段。
我有BottomNavigationView
和ViewPager
,它加载了4个片段-每个Fragment
都包含TabLayout
和ViewPager
,以加载至少2个片段。
可以想象,这是一个非常大的UI渲染(10多个片段)--尤其是当这些片段中包含一些重要的组件,如日历、条形图等时。
目前建议的解决方案:
当需要片段时控制UI加载-所以直到用户第一次访问该片段,才有理由加载它。
这似乎是绝对可能的,因为许多应用程序,包括Play商店,正在这样做。请参见示例here
在上面的视频示例中-UI组件在导航到选项卡完成后加载。它甚至有一个嵌入式加载符号。
1)我试图弄清楚如何做到这一点-在什么时候我会知道这个片段UI需要创建,而不是它已经创建?
2)另外,什么是片段生命周期回调,我将在那里启动UI创建过程?onResume()
意味着UI对用户可见,因此加载UI会滞后和延迟。
希望这足够清楚。
编辑:
我已经使用FragmentStatePagerAdapter
作为ViewPager
适配器。我注意到构造函数中的super(fm)
方法现在被弃用了:
ViewPagerAdapter(FragmentManager fm) {
super(fm); // this is deprecated
}
所以我把它改成:
ViewPagerAdapter(FragmentManager fm) {
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
}
BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT
:表示只有当前片段将处于Lifecycle.State.RESUMED状态。所有其他片段都在Lifecycle. State. STARTED处封顶。
这似乎很有用,因为只有当Fragment
对用户可见时,才会调用Fragment
的onResume()
。我可以使用这个指示以某种方式加载UI吗?
8条答案
按热度按时间u2nhd7ah1#
您的应用在启动时加载多个Fragment的原因很可能是您要一次初始化所有Fragment。相反,您可以在需要时初始化它们。然后从窗口使用
show
`hide到
attach\
detach,而无需重新填充整个布局。 简单解释一下:一旦用户点击
BottomNavigationView的项目,您就可以创建Fragment。在单击的项目上,您将检查是否未创建和未添加Fragment,然后创建它并添加。如果它已经创建,则使用
show()方法来显示已经可用的片段,并使用
hide()隐藏
BottomNavigationView的所有其他片段。 根据你的情况,
show()/
hide比
add()/
replace`更好,因为正如你所说,当你想显示它们时,你不想重新填充片段对于您的
ViewPager
,您可以从您所引用的示例中看到; PlayStore使用setOffscreenPageLimit
。这将允许您选择应该保持活动的View
的数量,否则将从开始通过Fragment的所有生命周期事件(如果视图是Fragment)被销毁和创建。在PlayStore应用程序的情况下,这可能是4-5,这就是为什么当你重新选择“编辑器的选择”选项卡时,它再次开始加载。如果你这样做,只有选中的和相邻的(右边的一个)碎片会被激活,屏幕外的其他碎片将被销毁。回答两个问题
如果你使用
show
/hide
,你不需要知道什么时候放大你的视图。它将被自动处理,不会滞后,因为它只是attaching
/detaching
视图没有膨胀。fcg9iug32#
这取决于您如何在Activity中初始化片段。可能你是在Activity的
onCreate
方法中初始化所有片段,而不是在选择BottomNavigation
item时初始化它,如下所示:要决定在视图页导航中一次加载多少页,可以用途:
setOffscreenPageLimit
。请试试这个。
vmjh9lq93#
我是用同一种应用程序,有多个标签,也标签有多个内部标签。
我使用了ViewPager方法的概念,其中有一个onPageSelected()方法,用于获取页面位置。
通过使用这个位置,我们正在检查当前的Fragment,并调用我们在该片段中创建的自定义方法,如在该片段中定义的onPageSelected()。
使用Fragment中的这个自定义方法onPageSelected(),我们检查列表是否可用,如果列表有数据,那么我们就不调用API,否则我们调用Api并加载该列表。
我认为你有同样的要求,如果你的标签有内部标签或viewpager,你可以遵循同样的概念,所以如果你的viewpager方法onpageSelected的当前片段在你的viewpager片段初始化的时候调用。
你必须调用像数据绑定或视图初始化这样的初始化,需要在onCreate()方法中调用,其他列表附件和API调用将由基于ViewPager onPageSelected调用的自定义方法onPageSelected管理。
让我知道如果你需要任何帮助。
yquaqz184#
您可以尝试只在
ViewPager
中拥有Fragment
s和FrameLayout
s。实际的Fragment
s可以添加到onResume()
中的FrameLayout
(在检查此Fragment
是否尚未连接之后)。如果BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT
按预期工作,它应该可以工作。dnph8jn45#
我建议您在需要时使用
BottomNavigationView.setOnNavigationItemSelectedListener
在片段UI之间切换。这个想法很简单,当用户滑动或选择不同的选项卡时,可见的片段被新片段替换。
ymzxtsji6#
一个接一个地加载片段。用许多占位符和stubs创建主片段布局,然后按您喜欢的顺序加载它们。在主片段加载后使用它的FragmentTransaction.replace()。
sy5wg1nm7#
你试过片段的
setUserVisibleHint()
方法吗只有当用户看到片段时才会调用此函数
7z5jn7bk8#
你只维护一个
ViewPager
怎么样?听起来很疯狂?在这种情况下,只需在底部选项卡之间切换时更改PagerAdapter
的数据集。让我们看看你是怎么做到的正如您提到的,您有4个片段,每个片段被分配到底部导航视图的一个单独的选项卡。每个都执行一些冗余工作,即拿着一个带有tab布局的
viewPager
并设置相同类型的适配器。因此,如果我们可以将这4个冗余任务合并为一个,那么我们将能够摆脱4个片段。由于只有一个viewPager
和一个适配器,因此如果我们将offScreenPageLimit
设置为1,我们将能够将片段加载计数从~10减少到2。让我们看一些例子,activity.xml应该是这样的
这是可选的,但我建议创建一个带有抽象方法
getTabTitle()
的PagerFragment抽象基类现在是时候创建我们的PagerAdapter类了
最后,在活动
这是基本的想法。你可以把自己的一些想法和它混合在一起,得到一个美妙的结果。让我知道它是否有用。
更新
回答你的问题,
1.我认为,通过我的解决方案,您可以实现与我在项目中所做的完全相同的视频行为。在我的解决方案中,如果你设置offset page limit为1,那么只有相邻的fragment会被提前创建。因此,片段创建将由适配器和视图页管理器处理,您无需担心它。
1.在我上面的解决方案中,你应该在
onCreateView()
中创建UI。