如何处理Android生命周期就像在YouTube应用程序中一样?

时间:2017-01-26 14:58:33

标签: android android-viewpager android-lifecycle android-tablayout bottomnavigationview

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;
        }
    });

3 个答案:

答案 0 :(得分:2)

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

来自Android Support Library (v4) Documentation

  

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

     

默认值:1

如果您有 4个标签,并且您希望它们全部保持闲置状态并且永远不会被销毁。重新创建(如YouTube应用),您可能需要将限制设置为 3

将YouTube应用作为一个案例场景(4个标签),我相信它的ViewPager或多或少地以这种方式定义:

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

修改 关于BottomNavigationView - 只要你将它链接到ViewPager,无论你使用这个还是TabLayout都没关系。但经过二读,我知道你根本不使用ViewPager,所以我想知道你使用了什么,这样我的帮助才能完成

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

答案 1 :(得分:0)

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

答案 2 :(得分: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链接。 link