【问题标题】:How to resume fragment on Bottom navigation menu click?如何在底部导航菜单单击上恢复片段?
【发布时间】:2020-03-23 02:30:22
【问题描述】:

我创建了包含 5 个项目的底部导航视图。在项目多次点击时,片段被重新创建 并多次存储到堆栈中。如果它在堆栈中可用,我想恢复片段而不弹出其他片段。

MainActivity.java

private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
            = new BottomNavigationView.OnNavigationItemSelectedListener() {

        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            switch (item.getItemId()) {

                case R.id.feed:
                    String feed_tag = getResources().getString(R.string.feed_tag);
                    if(!getSupportFragmentManager().popBackStackImmediate(feed_tag, 0)){
                        //fragment is not in backStack, create it
                    FeedFragment f1=new FeedFragment();
                        FragmentTransaction ft1 = getSupportFragmentManager().beginTransaction();
                        ft1.replace(R.id.fragment_container, f1, feed_tag).addToBackStack(feed_tag);
                        ft1.commit();
                    }
                    return true;

                case R.id.search:
                    String search_tag = getResources().getString(R.string.search_tag);

                    if((!getSupportFragmentManager().popBackStackImmediate(search_tag, 0)) {
                        SearchFragment f3 = new SearchFragment();
                        FragmentTransaction ft3 = getSupportFragmentManager().beginTransaction();
                        ft3.replace(R.id.fragment_container, f3, search_tag).addToBackStack(search_tag);
                        ft3.commit();
                    }
                    return true;

                case R.id.post:
                    String post_tag = getResources().getString(R.string.post_tag);

                    if(!getSupportFragmentManager().popBackStackImmediate(post_tag, 0);) {
                        Post postBase = new Post();
                        FragmentTransaction ft2 = getSupportFragmentManager().beginTransaction();
                        ft2.replace(R.id.fragment_container, postBase, post_tag).addToBackStack(post_tag);
                        ft2.commit();
                    }
                    return true;

                case R.id.noti:
                    String noti_tag = getResources().getString(R.string.notification_tag);
                    if(!getSupportFragmentManager().popBackStackImmediate(noti_tag, 0)) {
                        NotificationFragment f4 = new NotificationFragment();
                        FragmentTransaction ft4 = getSupportFragmentManager().beginTransaction();
                        ft4.replace(R.id.fragment_container, f4, noti_tag).addToBackStack(noti_tag);
                        ft4.commit();
                    }
                    return true;

                case R.id.profile:
                    String profile_tag = getResources().getString(R.string.profile_tag);
                    if(!getSupportFragmentManager().popBackStackImmediate(profile_tag, 0)) {
                        Fragment f5 = ProfileFragment.getInstance("val1", "val2");
                        FragmentTransaction ft5 = getSupportFragmentManager().beginTransaction();
                        ft5.replace(R.id.fragment_container, f5, profile_tag).addToBackStack(profile_tag);
                        ft5.commit();
                    }
                    return true;
            }
            return false;
        }
    };

如果我使用 POP_BACK_STACK_INCLUSIVE 标志,我点击的片段也会被删除,并且我得到了位于后台堆栈中点击片段下方的片段。

如何在不重新创建的情况下从后台堆栈中取回已添加的片段?

【问题讨论】:

  • 如果你使用replace而不是add/hide/show,无论你做什么,你的片段都会被重新创建。

标签: java bottomnavigationview


【解决方案1】:

你可以这样做。无需重新创建:

val firstFragment: Fragment = FirstFragment()
val secondFragment: Fragment = SecondFragment()
val thirdFragment: Fragment = ThirdFragment()

val navView: BottomNavigationView = findViewById(R.id.nav_view)

var active = firstFragment
fm.beginTransaction().add(R.id.nav_host_fragment, thirdFragment, "3").hide(thirdFragment).commit()
fm.beginTransaction().add(R.id.nav_host_fragment, secondFragment, "2").hide(secondFragment).commit()
fm.beginTransaction().add(R.id.nav_host_fragment, firstFragment, "1").commit()

navView.setOnNavigationItemReselectedListener {  }
navView.setOnNavigationItemSelectedListener { item ->
   when (item.itemId) {
       R.id.navigation_first -> {
           fm.beginTransaction().hide(active).show(firstFragment).commit()
           active = firstFragment

       }
       R.id.navigation_second -> {
           fm.beginTransaction().hide(active).show(secondFragment).commit()
           active = secondFragment
       }
       R.id.navigation_third -> {
           fm.beginTransaction().hide(active).show(thirdFragment).commit()
           active = thirdFragment
       }
   }
    true
 }

【讨论】:

  • 如果嵌套的片段是打开的,那么我无法得到底部导航菜单片段。
  • 如果您对嵌套片段使用替换,是的,选择的菜单项不起作用。您应该再次对嵌套片段使用 add 。例如:val nested = NestedFragment() activity!!.supportFragmentManager.beginTransaction().add(R.id.nav_host_fragment, nested, "4").hide(active).commit() active = nested
  • 如何管理来自不同文件位置的活动片段?
  • 这样调用(activity as YourActivity).active 在任何片段中。首先在YourActivity中定义active to public
  • 嘿,我在 backPressed 上遇到了 backstack 问题,因为已经添加的片段位于堆栈中的任何位置。你能帮我么? @Kasım Özdemir
猜你喜欢
  • 2021-11-07
  • 1970-01-01
  • 2017-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-23
  • 1970-01-01
相关资源
最近更新 更多