# FragmentMenu
**Repository Path**: amqr/FragmentMenu
## Basic Information
- **Project Name**: FragmentMenu
- **Description**: 记录Fragment声明周期,避免重复创建,每个Fragment独立拥有Toobar和menu
- **Primary Language**: Java
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 0
- **Created**: 2016-11-26
- **Last Updated**: 2020-12-19
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
>Toorbar现在已经被广泛使用了,但是多个Fragment之间使用Toorbar的使用可能会遇到menu消失的问题,单就本来这点不必成文,但是一想到好像还没有写过关Fragment声明周期的和复用的文章,就干脆记录一下算了,后面如果需要拿起来参考也算可以。
文章分三点进行描述,第一点说的是Fragment的生命周期,大可忽略之,第二点说的是如何利用add和hide避免重复创建Fragment,老生常谈也可忽略之,第三点说是让每一个Toolbar对应不同的Toolbar的menu,这个还是可以稍微参考一下的。
# 一、以事务replace方式简述生命周期
先上图,再代码,后分析

上代码
Activity
```
public class StyleFirstActivity extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener {
private RadioGroup mRbTab;
private RadioButton mRbOne;
private RadioButton mRbTwo;
private RadioButton mRbThree;
private RadioButton mRbFour;
private OneFragment oneFragment;
private TwoFragment twoFragment;
private ThreeFragment threeFragment;
private FourFragment fourFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRbTab = (RadioGroup) findViewById(R.id.mRbTab);
mRbOne = (RadioButton) findViewById(R.id.mRbOne);
mRbTwo = (RadioButton) findViewById(R.id.mRbTwo);
mRbThree = (RadioButton) findViewById(R.id.mRbThree);
mRbFour = (RadioButton) findViewById(R.id.mRbFour);
mRbTab.setOnCheckedChangeListener(this);
commitOneFrag();
}
// MainActivty实现接口的必须复写的方法
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
FragmentManager fm = getSupportFragmentManager(); // getSupportFragmentManager(); 才是v4的
FragmentTransaction transaction = fm.beginTransaction(); // Fragment的事务
switch (checkedId) {
case R.id.mRbOne:
if (oneFragment == null) {
oneFragment = new OneFragment();
}
transaction.replace(R.id.mFlWaitReplace, oneFragment);
break;
case R.id.mRbTwo:
if (twoFragment == null) {
twoFragment = new TwoFragment();
}
transaction.replace(R.id.mFlWaitReplace, twoFragment);
break;
case R.id.mRbThree:
if (threeFragment == null) {
threeFragment = new ThreeFragment();
}
transaction.replace(R.id.mFlWaitReplace, threeFragment);
break;
case R.id.mRbFour:
if (fourFragment == null) {
fourFragment = new FourFragment();
}
transaction.replace(R.id.mFlWaitReplace, fourFragment);
break;
}
transaction.commit();
}
private void commitOneFrag() {
OneFragment oneFrag = new OneFragment();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.mFlWaitReplace, oneFrag);
ft.commit();
}
}
```
布局文件
```
```
.
.
.
Fragment,四个都类似,以为OneFragmemt为例子
```
public class OneFragment extends Fragment {
private View rootView;
@Nullable
@Override
public View onCreateView(LayoutInflater infater, ViewGroup container, Bundle savedInstanceState) {
Log.d(GeneralConst.TAG,"OneFragment --- onCreateView");
rootView = View.inflate(getActivity(), R.layout.fragment_one, null);
initView();
return rootView;
}
private void initView() {
rootView.findViewById(R.id.mTvOne).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getActivity(),"FragmentOne的Tv点击",Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
Log.d(GeneralConst.TAG,"OneFragment --- onAttach");
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(GeneralConst.TAG,"OneFragment --- onCreate");
}
@Override
public void onStart() {
super.onStart();
Log.d(GeneralConst.TAG,"OneFragment --- onStart");
}
@Override
public void onResume() {
super.onResume();
Log.d(GeneralConst.TAG,"OneFragment --- onResume");
}
@Override
public void onPause() {
super.onPause();
Log.d(GeneralConst.TAG,"OneFragment --- onPause");
}
@Override
public void onStop() {
super.onStop();
Log.d(GeneralConst.TAG,"OneFragment --- onStop");
}
@Override
public void onDestroyView() {
super.onDestroyView();
Log.d(GeneralConst.TAG,"OneFragment --- onDestroyView");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(GeneralConst.TAG,"OneFragment --- onDestroy");
}
@Override
public void onDetach() {
super.onDetach();
Log.d(GeneralConst.TAG,"OneFragment --- onDetach");
}
}
```
Fragment和Activity的生命周期较为相似了。
只是Fragment有几个Activity中没有的新方法,这里需要重点介绍一下:
* onAttach方法:Fragment和Activity建立关联的时候调用。
* onCreateView方法:为Fragment加载布局时调用。
* onActivityCreated方法:当Activity中的onCreate方法执行完后调用。
* onDestroyView方法:Fragment中的布局被移除时调用。
* onDetach方法:Fragment和Activity解除关联的时候调用。
进入该Activity,依次点击第一,第二,第三,第四,第一个Fragment
现在对点击进行分析:
执行了5个生命周期方法,对比其他的这里只是,这里这是执行了5个,原因是因为我们一进入这个Activity默认就进入了第一个Activity,然后我们再次点击了第一个,相当于重复点击了两次第一个。
```
11-23 08:30:28.712 11279-11279/com.amqr.testfragment D/FragTest: OneFragment --- onAttach
11-23 08:30:28.712 11279-11279/com.amqr.testfragment D/FragTest: OneFragment --- onCreate
11-23 08:30:28.712 11279-11279/com.amqr.testfragment D/FragTest: OneFragment --- onCreateView
11-23 08:30:28.712 11279-11279/com.amqr.testfragment D/FragTest: OneFragment --- onStart
11-23 08:30:28.712 11279-11279/com.amqr.testfragment D/FragTest: OneFragment --- onResume
--- 分割线 ---
11-23 08:30:31.269 11279-11279/com.amqr.testfragment D/FragTest: OneFragment --- onAttach
11-23 08:30:31.269 11279-11279/com.amqr.testfragment D/FragTest: OneFragment --- onCreate
11-23 08:30:31.269 11279-11279/com.amqr.testfragment D/FragTest: OneFragment --- onPause
11-23 08:30:31.269 11279-11279/com.amqr.testfragment D/FragTest: OneFragment --- onStop
11-23 08:30:31.269 11279-11279/com.amqr.testfragment D/FragTest: OneFragment --- onDestroyView
11-23 08:30:31.269 11279-11279/com.amqr.testfragment D/FragTest: OneFragment --- onDestroy
11-23 08:30:31.269 11279-11279/com.amqr.testfragment D/FragTest: OneFragment --- onDetach
11-23 08:30:31.269 11279-11279/com.amqr.testfragment D/FragTest: OneFragment --- onCreateView
11-23 08:30:31.270 11279-11279/com.amqr.testfragment D/FragTest: OneFragment --- onStart
11-23 08:30:31.270 11279-11279/com.amqr.testfragment D/FragTest: OneFragment --- onResume
--- 分割线 ---
11-23 08:30:32.350 11279-11279/com.amqr.testfragment D/FragTest: TwoFragment --- onAttach
11-23 08:30:32.350 11279-11279/com.amqr.testfragment D/FragTest: TwoFragment --- onCreate
11-23 08:30:32.350 11279-11279/com.amqr.testfragment D/FragTest: OneFragment --- onPause
11-23 08:30:32.350 11279-11279/com.amqr.testfragment D/FragTest: OneFragment --- onStop
11-23 08:30:32.350 11279-11279/com.amqr.testfragment D/FragTest: OneFragment --- onDestroyView
11-23 08:30:32.350 11279-11279/com.amqr.testfragment D/FragTest: OneFragment --- onDestroy
11-23 08:30:32.350 11279-11279/com.amqr.testfragment D/FragTest: OneFragment --- onDetach
11-23 08:30:32.350 11279-11279/com.amqr.testfragment D/FragTest: TwoFragment --- onCreateView
11-23 08:30:32.351 11279-11279/com.amqr.testfragment D/FragTest: TwoFragment --- onStart
11-23 08:30:32.351 11279-11279/com.amqr.testfragment D/FragTest: TwoFragment --- onResume
--- 分割线 ---
11-23 08:30:33.033 11279-11279/com.amqr.testfragment D/FragTest: ThreeFragment --- onAttach
11-23 08:30:33.033 11279-11279/com.amqr.testfragment D/FragTest: ThreeFragment --- onCreate
11-23 08:30:33.033 11279-11279/com.amqr.testfragment D/FragTest: TwoFragment --- onPause
11-23 08:30:33.033 11279-11279/com.amqr.testfragment D/FragTest: TwoFragment --- onStop
11-23 08:30:33.033 11279-11279/com.amqr.testfragment D/FragTest: TwoFragment --- onDestroyView
11-23 08:30:33.033 11279-11279/com.amqr.testfragment D/FragTest: TwoFragment --- onDestroy
11-23 08:30:33.033 11279-11279/com.amqr.testfragment D/FragTest: TwoFragment --- onDetach
11-23 08:30:33.033 11279-11279/com.amqr.testfragment D/FragTest: ThreeFragment --- onCreateView
11-23 08:30:33.035 11279-11279/com.amqr.testfragment D/FragTest: ThreeFragment --- onStart
11-23 08:30:33.035 11279-11279/com.amqr.testfragment D/FragTest: ThreeFragment --- onResume
--- 分割线 ---
11-23 08:30:33.699 11279-11279/com.amqr.testfragment D/FragTest: FourFragment --- onAttach
11-23 08:30:33.700 11279-11279/com.amqr.testfragment D/FragTest: FourFragment --- onCreate
11-23 08:30:33.700 11279-11279/com.amqr.testfragment D/FragTest: ThreeFragment --- onPause
11-23 08:30:33.700 11279-11279/com.amqr.testfragment D/FragTest: ThreeFragment --- onStop
11-23 08:30:33.700 11279-11279/com.amqr.testfragment D/FragTest: ThreeFragment --- onDestroyView
11-23 08:30:33.700 11279-11279/com.amqr.testfragment D/FragTest: ThreeFragment --- onDestroy
11-23 08:30:33.700 11279-11279/com.amqr.testfragment D/FragTest: ThreeFragment --- onDetach
11-23 08:30:33.700 11279-11279/com.amqr.testfragment D/FragTest: FourFragment --- onCreateView
11-23 08:30:33.700 11279-11279/com.amqr.testfragment D/FragTest: FourFragment --- onStart
11-23 08:30:33.700 11279-11279/com.amqr.testfragment D/FragTest: FourFragment --- onResume
--- 分割线 ---
11-23 08:30:34.833 11279-11279/com.amqr.testfragment D/FragTest: OneFragment --- onAttach
11-23 08:30:34.833 11279-11279/com.amqr.testfragment D/FragTest: OneFragment --- onCreate
11-23 08:30:34.833 11279-11279/com.amqr.testfragment D/FragTest: FourFragment --- onPause
11-23 08:30:34.833 11279-11279/com.amqr.testfragment D/FragTest: FourFragment --- onStop
11-23 08:30:34.833 11279-11279/com.amqr.testfragment D/FragTest: FourFragment --- onDestroyView
11-23 08:30:34.833 11279-11279/com.amqr.testfragment D/FragTest: FourFragment --- onDestroy
11-23 08:30:34.834 11279-11279/com.amqr.testfragment D/FragTest: FourFragment --- onDetach
11-23 08:30:34.834 11279-11279/com.amqr.testfragment D/FragTest: OneFragment --- onCreateView
11-23 08:30:34.839 11279-11279/com.amqr.testfragment D/FragTest: OneFragment --- onStart
11-23 08:30:34.839 11279-11279/com.amqr.testfragment D/FragTest: OneFragment --- onResume
```
如上,我们看的出来,以这种方式构建,每次点击切换到一个Fragment,至少都会执行5个方法
```
onAttach
onCreate
onCreateView
onStart
onResume
```
如果是切换那么会相应交织着上一个被销毁的过程(正因为上一个被销毁,所以我们点击新的Fragment才会有重新创建)
这里关键是明白一点,我们这里的新切换的Fragment都会有一个onCreate和onCreateView过程,这在大多数情况下不是我们想要的,对于页面复杂的Fragment是比较消耗内存的,这不是我们想看到的。
产生这个问题的主要原因是我们采用了replace()方法来替换Fragment。
关于这个老生常谈的问题就到此为止。
> 关于Fragment生命周期可以参考[Android Fragment完全解析,关于碎片你所需知道的一切](http://blog.csdn.net/sinyu890807/article/details/8881711)
# 二、利用事务的add和hide复用Fragment
一样,一图二码三分析

Activity
```
public class StyleSecondActivity extends AppCompatActivity{
private Button[] mTabs;
// ======== 四个TAB
private OneFragment sOneFragment;
private TwoFragment sTwoFragment;
private ThreeFragment sThreeFragment;
private FourFragment sFourFragment;
private Fragment[] fragments;
private int index;
private int currentTabIndex;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_style_second);
mTabs = new Button[4];
mTabs[0] = (Button) findViewById(R.id.mBtOneFragment);
mTabs[1] = (Button) findViewById(R.id.mBtTwoFragment);
mTabs[2] = (Button) findViewById(R.id.mBtThreeFragment);
mTabs[3] = (Button) findViewById(R.id.mBtFourFragment);
// select first tab
mTabs[0].setSelected(true);
// 实例化Tab
sOneFragment = new OneFragment();
sTwoFragment = new TwoFragment();
sThreeFragment = new ThreeFragment();
sFourFragment = new FourFragment();
fragments = new Fragment[]{sOneFragment, sTwoFragment, sThreeFragment, sFourFragment};
// 一开始只把 第一个 和 第二个 Fragment添加到事务里面,(方便切换时有数据)
// 然后默认展示第一个,第二个隐藏起来
getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, sOneFragment)
.add(R.id.fragment_container, sTwoFragment).hide(sTwoFragment).show(sOneFragment)
.commit();
}
/**
* 每一个按钮都带有android:onClick="onTabClicked"
* 不采用常规的复写onClick而采用这种方式,是为了统一操作这些按钮
* @param view
*/
public void onTabClicked(View view) {
switch (view.getId()) {
case R.id.mBtOneFragment:
index = 0;
break;
case R.id.mBtTwoFragment:
index = 1;
break;
case R.id.mBtThreeFragment:
index = 2;
break;
case R.id.mBtFourFragment:
index = 3;
break;
}
if (currentTabIndex != index) { // 切换了Fragment
FragmentTransaction trx = getSupportFragmentManager().beginTransaction();
trx.hide(fragments[currentTabIndex]); // 隐藏原来的
if (!fragments[index].isAdded()) { // 如果当前的没有被添加到FragmentTransaction,添加之
trx.add(R.id.fragment_container, fragments[index]);
}
trx.show(fragments[index]).commit(); // 添加事务,切换Fragment
}
mTabs[currentTabIndex].setSelected(false);
mTabs[index].setSelected(true);
currentTabIndex = index;
}
}
```
布局文件
```
、
```
这里的布局我调整了一下,这样的布局使用了后期需要添加比如小红点之类的特殊需求
至于Fragment,同第一大点,就不附加了。
.
.
.
分析
运行,然会我们分别点击 1234 1332 ,(1代表第一个Fragment)
```
11-23 09:45:28.081 16526-16526/com.amqr.testfragment D/FragTest: OneFragment --- onAttach
11-23 09:45:28.082 16526-16526/com.amqr.testfragment D/FragTest: OneFragment --- onCreate
11-23 09:45:28.082 16526-16526/com.amqr.testfragment D/FragTest: TwoFragment --- onAttach
11-23 09:45:28.082 16526-16526/com.amqr.testfragment D/FragTest: TwoFragment --- onCreate
11-23 09:45:28.082 16526-16526/com.amqr.testfragment D/FragTest: OneFragment --- onCreateView
11-23 09:45:28.082 16526-16526/com.amqr.testfragment D/FragTest: TwoFragment --- onCreateView
11-23 09:45:28.083 16526-16526/com.amqr.testfragment D/FragTest: OneFragment --- onStart
11-23 09:45:28.083 16526-16526/com.amqr.testfragment D/FragTest: TwoFragment --- onStart
11-23 09:45:28.083 16526-16526/com.amqr.testfragment D/FragTest: OneFragment --- onResume
11-23 09:45:28.083 16526-16526/com.amqr.testfragment D/FragTest: TwoFragment --- onResume
--- 分割线 ---
11-23 09:45:32.124 16526-16526/com.amqr.testfragment D/FragTest: ThreeFragment --- onAttach
11-23 09:45:32.124 16526-16526/com.amqr.testfragment D/FragTest: ThreeFragment --- onCreate
11-23 09:45:32.124 16526-16526/com.amqr.testfragment D/FragTest: ThreeFragment --- onCreateView
11-23 09:45:32.125 16526-16526/com.amqr.testfragment D/FragTest: ThreeFragment --- onStart
11-23 09:45:32.125 16526-16526/com.amqr.testfragment D/FragTest: ThreeFragment --- onResume
--- 分割线 ---
11-23 09:45:33.003 16526-16526/com.amqr.testfragment D/FragTest: FourFragment --- onAttach
11-23 09:45:33.003 16526-16526/com.amqr.testfragment D/FragTest: FourFragment --- onCreate
11-23 09:45:33.004 16526-16526/com.amqr.testfragment D/FragTest: FourFragment --- onCreateView
11-23 09:45:33.004 16526-16526/com.amqr.testfragment D/FragTest: FourFragment --- onStart
11-23 09:45:33.004 16526-16526/com.amqr.testfragment D/FragTest: FourFragment --- onResume
```
我们一旦进入Activity,首先因为代码的关系,我们先让Fragment的事务添加进入第一个和第二个Fragment
所以在什么都没有点击的情况下,先执行了
```
11-23 09:45:28.081 16526-16526/com.amqr.testfragment D/FragTest: OneFragment --- onAttach
11-23 09:45:28.082 16526-16526/com.amqr.testfragment D/FragTest: OneFragment --- onCreate
11-23 09:45:28.082 16526-16526/com.amqr.testfragment D/FragTest: TwoFragment --- onAttach
11-23 09:45:28.082 16526-16526/com.amqr.testfragment D/FragTest: TwoFragment --- onCreate
11-23 09:45:28.082 16526-16526/com.amqr.testfragment D/FragTest: OneFragment --- onCreateView
11-23 09:45:28.082 16526-16526/com.amqr.testfragment D/FragTest: TwoFragment --- onCreateView
11-23 09:45:28.083 16526-16526/com.amqr.testfragment D/FragTest: OneFragment --- onStart
11-23 09:45:28.083 16526-16526/com.amqr.testfragment D/FragTest: TwoFragment --- onStart
11-23 09:45:28.083 16526-16526/com.amqr.testfragment D/FragTest: OneFragment --- onResume
11-23 09:45:28.083 16526-16526/com.amqr.testfragment D/FragTest: TwoFragment --- onResume
```
然会我们点击分别点击1和2,日志没有变化,这就对了,这就是我们想要的结果
我们点击3的时候,日志输出了
```
11-23 09:45:32.124 16526-16526/com.amqr.testfragment D/FragTest: ThreeFragment --- onAttach
11-23 09:45:32.124 16526-16526/com.amqr.testfragment D/FragTest: ThreeFragment --- onCreate
11-23 09:45:32.124 16526-16526/com.amqr.testfragment D/FragTest: ThreeFragment --- onCreateView
11-23 09:45:32.125 16526-16526/com.amqr.testfragment D/FragTest: ThreeFragment --- onStart
11-23 09:45:32.125 16526-16526/com.amqr.testfragment D/FragTest: ThreeFragment --- onResume
```
我们点击4的时候,日志产生的结果是
```
11-23 09:45:33.003 16526-16526/com.amqr.testfragment D/FragTest: FourFragment --- onAttach
11-23 09:45:33.003 16526-16526/com.amqr.testfragment D/FragTest: FourFragment --- onCreate
11-23 09:45:33.004 16526-16526/com.amqr.testfragment D/FragTest: FourFragment --- onCreateView
11-23 09:45:33.004 16526-16526/com.amqr.testfragment D/FragTest: FourFragment --- onStart
11-23 09:45:33.004 16526-16526/com.amqr.testfragment D/FragTest: FourFragment --- onResume
```
(因为3和4我们之前还没有添加进入事务里面)
再后来,我们分别切换到1、3、3和4的时候,日志无变化,这也对了。
因为我们采取的是add和hide,添加和隐藏嘛。
.
.
.
# 三、每一个Fragment对应一个Toolbar和menu
一图二码三分析

gif说明:第二个Fragment弹出菜单的的红色是因为模拟器的关系,真机完美运行你懂得。
上代码
Activity
以这种add和hide的方式就不会每次都执行onCreateView,避免效果必要的内存。
```
/**
*
* 整体思路,一进入Activity只add进入头两个Fragment,而且hide第二个,展示第一个
* 以后如果切换到任意的Fragment,那么先判断事务里面有没有这个Fragment,
* 无则加之,然后隐藏上一个,展示当前新切换到的
* 有则隐藏上一个,展示当前的新切换到的
*/
public class StyleSecondActivity extends AppCompatActivity {
private Button[] mTabs;
// ======== 四个TAB
private OneFragment sOneFragment;
private TwoFragment sTwoFragment;
private ThreeFragment sThreeFragment;
private FourFragment sFourFragment;
private Fragment[] fragments;
private int index;
private int currentTabIndex;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_style_second);
mTabs = new Button[4];
mTabs[0] = (Button) findViewById(R.id.mBtOneFragment);
mTabs[1] = (Button) findViewById(R.id.mBtTwoFragment);
mTabs[2] = (Button) findViewById(R.id.mBtThreeFragment);
mTabs[3] = (Button) findViewById(R.id.mBtFourFragment);
// select first tab
mTabs[0].setSelected(true);
// 实例化Tab
sOneFragment = new OneFragment();
sTwoFragment = new TwoFragment();
sThreeFragment = new ThreeFragment();
sFourFragment = new FourFragment();
fragments = new Fragment[]{sOneFragment, sTwoFragment, sThreeFragment, sFourFragment};
// 一开始只把 第一个 和 第二个 Fragment添加到事务里面,(方便切换时有数据)
// 然后默认展示第一个,第二个隐藏起来
getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, sOneFragment)
.add(R.id.fragment_container, sTwoFragment).hide(sTwoFragment).show(sOneFragment)
.commit();
}
/**
* 每一个按钮都带有android:onClick="onTabClicked"
* 不采用常规的复写onClick而采用这种方式,是为了统一操作这些按钮
* @param view
*/
public void onTabClicked(View view) {
switch (view.getId()) {
case R.id.mBtOneFragment:
index = 0;
break;
case R.id.mBtTwoFragment:
index = 1;
break;
case R.id.mBtThreeFragment:
index = 2;
break;
case R.id.mBtFourFragment:
index = 3;
break;
}
if (currentTabIndex != index) { // 切换了Fragment
FragmentTransaction trx = getSupportFragmentManager().beginTransaction();
trx.hide(fragments[currentTabIndex]); // 隐藏原来的
if (!fragments[index].isAdded()) { // 如果当前的没有被添加到FragmentTransaction,添加之
trx.add(R.id.fragment_container, fragments[index]);
}
trx.show(fragments[index]).commit(); // 添加事务,切换Fragment
}
mTabs[currentTabIndex].setSelected(false);
mTabs[index].setSelected(true);
currentTabIndex = index;
}
}
```
.
.
.
两个Fragment
SpcOneFragment
```
public class SpcOneFragment extends Fragment {
private View rootView;
private Toolbar mToolBar;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.d(GeneralConst.TAG,"SpcOneFragment --- onCreateView");
rootView = View.inflate(getActivity(), R.layout.fragment_spc_one, null);
initView();
setHasOptionsMenu(true); // 让Fragment的菜单按钮生效
return rootView;
}
private void initView() {
rootView.findViewById(R.id.mTvOne).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getActivity(),"SpcOneFragment的Tv点击",Toast.LENGTH_SHORT).show();
}
});
mToolBar = (Toolbar) rootView.findViewById(R.id.mToolBar);
mToolBar.setTitle("拥抱世界");
((AppCompatActivity) getActivity()).setSupportActionBar(mToolBar); // 这样切换后Fragment会失效
mToolBar.setOverflowIcon(getResources().getDrawable(R.drawable.icon_menu)); // 指定菜单按钮图标
mToolBar.inflateMenu(R.menu.menu_diy);
//mToolBar.inflateMenu(R.menu.menu_diy);
mToolBar.setOnMenuItemClickListener(onMenuItemClick); // 菜单按钮点击监听
mToolBar.setNavigationIcon(R.drawable.arrow_left); // 返回箭头
mToolBar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
getActivity().finish();
}
});
}
// 创建关联菜单
// 下面这里先clean后inflate这么写是为了避免Fragment和Activity同是带有Toolbar,再加重复的东西
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
//((AppCompatActivity) getActivity()).getMenuInflater().inflate(R.menu.menu_diy, menu);
menu.clear();
inflater.inflate(R.menu.menu_diy, menu);
super.onCreateOptionsMenu(menu, inflater);
}
// 菜单的点击回调
private Toolbar.OnMenuItemClickListener onMenuItemClick = new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.item_hello:
Toast.makeText(getActivity(),"白衣少年",Toast.LENGTH_SHORT).show();
break;
case R.id.item_boy:
Toast.makeText(getActivity(),"少年,热闹海岸线",Toast.LENGTH_SHORT).show();
break;
}
return true;
}
};
}
```
布局文件
```
```
menu文件
```
```
另外一个Fragment就不附代码了,类似。
分析阶段:
我们想让每个Fragment都对应有自己的menu,就要注意下面几步
1、在onCreateView里面执行
`
setHasOptionsMenu(true); // 让Fragment的菜单按钮生效
`
而且最好是在所有Toolbar相关操作的前面,不然可能不生效
2、在onCreateOptionsMenu方法里面使用
`
inflater.inflate(R.menu.menu_diy, menu);
`
这样方式去加载menu文件,而不是
`
((AppCompatActivity)getActivity()).getMenuInflater().inflate(R.menu.menu_diy, menu);
`
嗯,大概就是这样啦。
如果你想说为什么我第二个Fragment可以这样子背景、颜色位置,两个Fragment的溢出菜单的样式可以自定义,那么请你看下我的style文件和关于Fragment的布局文件
style文件,重点看AppTheme3和OverflowMenuStyle
```
```
.
.
.
然后你看一下我第二个Fragment的布局文件

机智如你,必然明了。
本文至此完。
***
代码链接
[git Link](https://git.oschina.net/amqr/FragmentMenu)
[csdn Link](http://download.csdn.net/detail/icoollike/9694260)