@andreytecho

Как реализовать вложенные фрагменты в viewpager с разными меню?

Я хочу создать Activity с 2-мя фрагментами во ViewPager (также есть переключение по TabLayout), У этих фрагментов разные опции меню, и они являются вложенными (то есть по клику ListView Item-а открывается второй такой же фрагмент но с другими данными). По логике это можно реализовать если менять контент внутри ViewPagera (выполнив
transaction.replace(R.id.viewpager, new Fragment(), transaction.addToBackStack()).
Но к сожалению, это не работает (вместо фрагмента с данными появляется пустой фрагмент).
Я нашел одно решение - stackoverflow.com/a/18020219/5576117, но т.к. у меня используются различные опции меню, оно мне тоже не подходит (onCreateOptionsMenu будет вызываться у FragmentContainer-a).

В итоге я сделал простой boolean extra, который передаю в случае когда фрагмент является контейнером и это работает, но теперь появилась новая проблема - метод onOptionsItemSelected вызывается из второго фрагмента, даже когда в ViewPager-е выбран первый.

Код:
MainActivity:

@Override
    protected void onCreate(Bundle savedInstanceState) {    
         ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
         viewPager.addOnPageChangeListener(this);
         setupViewPager(viewPager);
        
         TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
         tabLayout.setupWithViewPager(viewPager);
    }
        
    private void setupViewPager(ViewPager viewPager) {
         viewPager.setOffscreenPageLimit(2);
         mAdapter = new MainViewPagerAdapter(getSupportFragmentManager());
       
         TwoFragment fragment = new TwoFragment();
         Bundle args = new Bundle(1);
         args.putBoolean(TwoFragment.ISCONTAINER_EXTRA, true);
         fragment.setArguments(args);
         mAdapter.addFragment(fragment, "TAB1");
         mAdapter.addFragment(new OneFragment(), "TAB2");
    }


OneFragment:

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
         View view = inflater.inflate(R.layout.fragment_one, container, false);
         setHasOptionsMenu(true);
         return view;
    }
        
    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
         super.onCreateOptionsMenu(menu, inflater);
         menu.clear();
         inflater.inflate(R.menu.menu_one, menu);
    }
        
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
         // Метод не вызывается даже когда этот фрагмент выбран во ViewPager-е
         return true;
    }


TwoFragment:

@Override
    public void onCreate(Bundle savedInstanceState) {
       Bundle extras = getArguments();
       if (extras != null && extras.containsKey(ISCONTAINER_EXTRA)) {
           isContainer = extras.getBoolean(ISCONTAINER_EXTRA);
       }
           
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
       if (isContainer) {
           setHasOptionsMenu(false);
           FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
           transaction.replace(R.id.clRoot, new TwoFragment()).commit();
           return inflater.inflate(R.layout.fragment_two, container, false);
        }
        View view = inflater.inflate(R.layout.fragment_two, container, false);
        setHasOptionsMenu(true);
        // Other actions
        return view;
        }
            
    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);
        menu.clear();
        inflater.inflate(R.menu.menu_two, menu);
    }
          
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // А вот этот вызывается всегда
        switch (item.getItemId()) {
            case android.R.id.home:
                getFragmentManager().popBackStack();
                break;
            case R.id.action_settings:
                startActivity(new Intent(getActivity(), SettingsActivity.class));
                break;
            case R.id.action_exit:
                Intent homeIntent = new Intent(Intent.ACTION_MAIN);
                homeIntent.addCategory(Intent.CATEGORY_HOME);
                homeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(homeIntent);
                break;
        }
        return true;
    }


Можно ли как то всё это реализовать без использования сторонних библиотек?
  • Вопрос задан
  • 1733 просмотра
Пригласить эксперта
Ответы на вопрос 1
@andreytecho Автор вопроса
Ответ нашёл здесь (видел раньше такой совет, но к сожалению, не попробовал): https://tausiq.wordpress.com/2014/06/06/android-mu... (В статье используется библиотека ViewPagerIndicator, но она может быть легко заменена на TabLayout).

Основная идея: вынести tablayout и viewpager из activity в fragment. Проверил у себя - все работает отлично.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы