0

YouTube 如何处理其标签片段的生命周期?当我点击选项卡时,即使我切换了该选项卡,它也会开始并继续加载数据。当我再次重新选择该选项卡时,它不会重新加载它的视图和数据。我认为有一些布尔变量,如 didFeedLoad,然后在 onCreate 中设置为 true?但在我看来,这不是优雅和好的解决方案。你怎么看?

在我的应用程序而不是 ViewPager 和 TabLayout 中,我有 BottomNavigationView,但我想像在 YouTube Android 应用程序中一样处理生命周期

下面是导航代码:

FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frame_layout, new OneFragment());
fragmentTransaction.commit();
BottomNavigationView bottomNavigationView =
            (BottomNavigationView) findViewById(R.id.bottom_navigation_view);

bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            Fragment fragment = null;
            switch (item.getItemId()) {
                case R.id.action_one:
                    fragment = new OneFragment();
                    break;
                case R.id.action_two:
                    fragment = new TwoFragment();
                    break;
                case R.id.action_three:
                    fragment = new ThreeFragment();
                    break;
                case R.id.action_four:
                    fragment = new FourFragment();
                    break;
                case R.id.action_five:
                    fragment = new FiveFragment();
                    break;
            }
            if (fragment != null) {
                FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
                fragmentTransaction.replace(R.id.frame_layout, fragment);
                fragmentTransaction.commit();
            }
            return true;
        }
    });
4

3 回答 3

3

您正在寻找的是 ViewPager .setOffscreenPageLimit(int limit)

来自Android 支持库 (v4) 文档

设置应保留到处于空闲状态的视图层次结构中当前页面的任一侧的页面数。超出此限制的页面将在需要时从适配器重新创建。

默认值:1

如果您有4 个 Tabs,并且您希望它们都保持空闲状态并且永远不会被破坏和重新创建(如 YouTube 应用程序),您可能需要将限制设置为3

以 YouTube 应用为例(4 个标签),我相信它的 ViewPager 或多或少是这样定义的:

ViewPager mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setOffscreenPageLimit(3);

编辑: 关于 BottomNavigationView - 只要将其链接到 ViewPager,使用这个或 TabLayout 都没有关系。但是经过第二次阅读后,我了解到您根本没有使用 ViewPager,所以我想知道您使用的是什么,以便我的帮助可以完成

(此外,为什么不使用 ViewPager?它看起来是完美的解决方案)

于 2017-01-26T15:40:42.830 回答
0

我怀疑 YouTube 标签的片段是正常的片段。当您切换选项卡时,它们可能(并且可能)被杀死。他们只是在后台(在主要活动/不同线程上)加载数据,然后在本地缓存/存储该数据,因此当您再次切换到同一选项卡时,它会使用存储/缓存的数据非常快速地重新绘制。

于 2017-01-26T15:36:27.610 回答
0

每次单击底部导航视图选项卡时,您都会加载一个新的片段实例。

你要做的是,一旦你创建了片段的一个实例,

那么你必须像这样使用支持片段管理器的隐藏和显示方法......

  { supportFragmentManager.beginTransaction().hide(currentFragment!!).show(prev_fragment).commit()
  }

下面我写了完整的实现。

 class MainActivity : AppCompatActivity() 

         {

      private lateinit var bottomNavigation:BottomNavigationView
 private var currentTag:String="null"
 private var currentFragment:Fragment?=null
  private lateinit var homeFragment:Fragment
 private lateinit var midFragment:Fragment
 private lateinit var profileFragment:Fragment
 override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

     init()
}

 private fun init() {
     homeFragment= HomeFragment()
     midFragment= MidFragment()
     profileFragment= ProfileFragment()

     bottomNavigation=findViewById(R.id.btm_nav)
     bottomNavigation.setOnNavigationItemSelectedListener(object :BottomNavigationView.OnNavigationItemSelectedListener{
         override fun onNavigationItemSelected(item: MenuItem): Boolean {
             when(item.itemId){
                 R.id.action_home->{


                     updateFragment(homeFragment,"home")
                 return true
                 }
                 R.id.action_mid->{

                     updateFragment(midFragment,"mid")
                 return true
                 }
                 R.id.action_profile->{
                     updateFragment(profileFragment,"profile")
        return true
                 }

             }
        return false

         }

     })
     updateFragment(homeFragment,"home")
 }

 fun updateFragment(fragment:Fragment, tag:String){

     if (currentTag.equals(tag)){
         return
     }
     var prev_fragment=supportFragmentManager.findFragmentByTag(tag)

     // if fragment is not present in stack
     if (prev_fragment==null){
         if (currentFragment==null){
             supportFragmentManager.beginTransaction().add(R.id.frag_container,fragment,tag).commit()
         }else{
             supportFragmentManager.beginTransaction().hide(currentFragment!!).add(R.id.frag_container,fragment,tag).commit()
         }

     }
   // if fragment is already added
     else{
         supportFragmentManager.beginTransaction().hide(currentFragment!!).show(prev_fragment).commit()
     }
     currentFragment=fragment
     currentTag=tag

 }

如果您还想维护片段的后堆栈,我已经设法在堆栈的帮助下做到了这一点。这是完整代码的 GitHub 链接。 关联

于 2019-08-07T05:22:47.333 回答