Android 具有不同菜单的viewpager中的嵌套片段

Android 具有不同菜单的viewpager中的嵌套片段,android,android-fragments,android-viewpager,Android,Android Fragments,Android Viewpager,问题 我想在一个活动中创建包含2个片段的viewpager。 此片段具有不同的菜单选项,其中一个片段是嵌套的-通过单击listview项,打开具有新数据的相同片段(replace(),addToBackStack()),但viewpager没有正确替换(当我执行transaction.replace(R.id.viewpager,new TwoFragment())) 我使用了这个答案-,但我有不同的菜单选项,菜单选项从片段容器中膨胀 因此,如果我创建一个新的片段(作为容器),我只需将布尔额外i

问题

我想在一个活动中创建包含2个片段的viewpager。 此片段具有不同的菜单选项,其中一个片段是嵌套的-通过单击listview项,打开具有新数据的相同片段(
replace(),addToBackStack()
),但viewpager没有正确替换(当我执行
transaction.replace(R.id.viewpager,new TwoFragment())

我使用了这个答案-,但我有不同的菜单选项,菜单选项从片段容器中膨胀

因此,如果我创建一个新的片段(作为容器),我只需将布尔额外
isContainer
传递给片段,这样就可以了。 但是现在活动调用错误的onOptions ItemSelected方法(当在viewpager中选择fragment1时,从
fragment2
调用)

我的代码

main活动:

@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");
}
@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) {
     // This method not called then this fragment selected in viewpager
     return true;
}
@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) {
    // This method called then always
    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;
}
OneFragment:

@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");
}
@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) {
     // This method not called then this fragment selected in viewpager
     return true;
}
@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) {
    // This method called then always
    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;
}
TwoFragment:

@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");
}
@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) {
     // This method not called then this fragment selected in viewpager
     return true;
}
@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) {
    // This method called then always
    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;
}
问题

如果不使用第三方库,我如何实现这一点

注:对不起,我的英语不好。

在这里回答:(在本例中使用了viewpagerindicator库,但它可以很容易地被TableLayout替换)


主要思想:创建根片段,并在此片段中放置您的viewpager、TableLayout和其他片段。一切正常。

如果我确实理解您的意思,您唯一的问题是现在没有显示选项菜单,您可能可以这样做

 pager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener(){
        @Override public void onPageSelected(int position) {
            supportInvalidateOptionsMenu();
        }
    });
每当您在
片段
中选择一个页面时,这将
重新使菜单无效,您可以通过调用

((getActivity())AppCompatActivity).supportInvalidateOptionsMenu();

这将使每个被替换的
片段上的菜单无效

感谢您的响应,我尝试了此方法,但也调用了错误的OnOptions ItemSelected方法。您能否通过调用错误的OnOptions ItemSelected来解释更多内容?因为如果您的菜单位于嵌套片段中,则必须在嵌套片段中实现OnOptions ItemSelectedt、 不在活动中抱歉等待,我的意思是当在viewpager中选择fragment2时调用OnOptions ItemSelected from fragment1。