In my application there is a BottomNavigationView through which fragments are opened. I have two snippets from TabLayout (employees, messages). When you click on the staff, everything works, then when you click on messages, the TabLayout continues to work, but if you re-open the messages, TabLayout bugs and shows nothing. I suppose that the error lies in my .replace, where just new fragments are created. How to open a fragment from backStack, or how it should be implemented?

public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) { FragmentManager fm = getSupportFragmentManager(); switch (menuItem.getItemId()) { case R.id.navigation_messages: if(fm.findFragmentByTag(MessagesFragment.TAG) == null) { fm.beginTransaction() .replace(R.id.fragment_container_main, new MessagesFragment(), MessagesFragment.TAG) .addToBackStack(MessagesFragment.TAG) .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE) .commit(); } // Как снова показать фрагмент из backStack? return true; case R.id.navigation_events: Toast.makeText(this,menuItem.getTitle(),Toast.LENGTH_SHORT).show(); return true; case R.id.navigation_mailing_lists: Toast.makeText(this,menuItem.getTitle(),Toast.LENGTH_SHORT).show(); return true; case R.id.navigation_employees: if(fm.findFragmentByTag(UsersFragment.TAG) == null) { fm.beginTransaction() .replace(R.id.fragment_container_main, new UsersFragment(), UsersFragment.TAG) .addToBackStack(UsersFragment.TAG) .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE) .commit(); } // Как снова показать фрагмент из backStack? return true; case R.id.navigation_menu: Toast.makeText(this,menuItem.getTitle(),Toast.LENGTH_SHORT).show(); return true; } return false; } 

And plus to everything I read that fragments in fragments are not gud.

PS: Does it make sense to use fragments in such situations? Or it is better to work with several activations for each menu item.

UPD: Message Fragment Code:

 public class MessagesFragment extends Fragment { public static final String TAG = MessagesFragment.class .getSimpleName(); private View mRootView; private FloatingActionButton mNewMessageButton; private TabLayout mTabLayout; private ViewPager mViewPager; private MessagesPagerAdapter mAdapter; @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { mRootView = inflater.inflate(R.layout.fragment_messages, container, false); mTabLayout = mRootView.findViewById(R.id.tab_layout_messages); mViewPager = mRootView.findViewById(R.id.view_pager_messages); mNewMessageButton = mRootView.findViewById(R.id.fab_new_message); mAdapter = new MessagesPagerAdapter(getFragmentManager()); mAdapter.addFragment(new MessagesInboxFragment(), "Входящие"); mAdapter.addFragment(new MessagesOutboxFragment(), "Исходящие"); mViewPager.setAdapter(mAdapter); mTabLayout.setupWithViewPager(mViewPager); mNewMessageButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startActivity(new Intent(mRootView.getContext(), NewMessageActivity.class)); } }); return mRootView; } } 

Adapter:

 public class MessagesPagerAdapter extends FragmentPagerAdapter { private List<Fragment> mFragmentsMessages = new ArrayList<>(); private List<String> mFragmentsMessagesTitles = new ArrayList<>(); public MessagesPagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int i) { return mFragmentsMessages.get(i); } @Override public int getCount() { return mFragmentsMessages.size(); } @Nullable @Override public CharSequence getPageTitle(int position) { return mFragmentsMessagesTitles.get(position); } public void addFragment(Fragment fragment, String title) { mFragmentsMessages.add(fragment); mFragmentsMessagesTitles.add(title); } } 

    1 answer 1

    TabLayout does not interfere with normal implementation. But, I for a start would put the code in order, at least. Although I will not give the perfect option, but try to do something like this:

     public class Main extends AppCompatActivity implements BottomNavigationView.OnNavigationItemSelectedListener { private Fragment mFirstFragment = new FirstFragment(); private Fragment mSecondFragment = new SecondFragment(); if (savedInstanceState == null) { loadFragment(mFirstFragment); } bottomNavigationView.setOnNavigationItemSelectedListener(this); @Override public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) { Fragment fragment = null; if (bottomNavigationView.getSelectedItemId() != menuItem.getItemId()) { switch (menuItem.getItemId()) { case R.id.navigation_main: fragment = mFirstFragment; break; case R.id.navigation_taxi: fragment = mFirstFragment; break; case R.id.navigation_bus: fragment = mSecondFragment; break; case R.id.navigation_train: fragment = mSecondFragment; break; } } return loadFragment(fragment); } private boolean loadFragment(Fragment fragment) { if (fragment != null) { getSupportFragmentManager() .beginTransaction() .replace(R.id.contentLayout, fragment) .commit(); return true; } return false; } @Override public void onBackPressed() { int selectedItemId = bottomNavigationView.getSelectedItemId(); if (R.id.navigation_main != selectedItemId) { loadFragment(mFirstFragment); bottomNavigationView.setSelectedItemId(R.id.navigation_main); } else { super.onBackPressed(); } } 
    • This is all good, but this is not a solution to my problem - Roman Romashov
    • There is essentially no difference between fragments or activation in terms of output on the screen. You have a problem in the adapter code or somewhere else. show the ViewPagera code and fragments - Romanych
    • I updated the question - Roman Romashov