一般在Activity里使用Toolbar如下: toolbar.xml
1 2 3 4 5 6 7 8 <?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.Toolbar xmlns:android ="http://schemas.android.com/apk/res/android" android:id ="@+id/toolbar" android:layout_width ="match_parent" android:layout_height ="wrap_content" android:background ="?attr/colorPrimary" android:minHeight ="?actionBarSize" > </android.support.v7.widget.Toolbar >
xml调用:
1 <include layout ="@layout/toolbar" />
Activity一般写到基类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public Toolbar initToolbar (int title) { Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); ActionBar actionBar = getSupportActionBar(); if (actionBar != null ) { actionBar.setDisplayHomeAsUpEnabled(true ); } return toolbar; } public Toolbar initToolbar (CharSequence title) { Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); ActionBar actionBar = getSupportActionBar(); if (actionBar != null ) { actionBar.setDisplayHomeAsUpEnabled(true ); } return toolbar; }
Activity调用:
现在项目需求,每个title不一样,就不能像以上一样写一个toolbar,放在最外层。问题来了,Fragment如何使用Toolbar像上面一样写吗?No,Fragment没有setSupportActionBar,于是Google,得到:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 public class BaseFragment extends Fragment { Activity mActivity; AppCompatActivity mAppCompatActivity; @Override public void onViewCreated (View view, Bundle savedInstanceState) { super .onViewCreated(view, savedInstanceState); mActivity = getActivity(); } public Toolbar initToolbar (int title) { AppCompatActivity mAppCompatActivity = (AppCompatActivity) mActivity; Toolbar toolbar = (Toolbar) mAppCompatActivity.findViewById(R.id.toolbar); mAppCompatActivity.setSupportActionBar(toolbar); ActionBar actionBar = mAppCompatActivity.getSupportActionBar(); if (actionBar != null ) { actionBar.setDisplayHomeAsUpEnabled(false ); } return toolbar; } public Toolbar initToolbar (CharSequence title) { mAppCompatActivity = (AppCompatActivity) mActivity; Toolbar toolbar = (Toolbar) mAppCompatActivity.findViewById(toolbarId); mAppCompatActivity.setSupportActionBar(R.id.toolbar); ActionBar actionBar = mAppCompatActivity.getSupportActionBar(); if (actionBar != null ) { actionBar.setDisplayHomeAsUpEnabled(false ); } return toolbar; } }
这样就解决Fragment使用Toolbar,却抛出了一个问题:Fragment标题错乱。
Fragment标题错乱 当出来这个问题时,我恍然大悟,Fragment里的Toolbar findViewById取的都是MainActivity,include不能共用一个ID,应该加个ID区别一下:
1 2 3 <include android:id ="@+id/program_toolbar" layout ="@layout/toolbar" />
BaseFragment 做相应的修改:
1 2 3 4 5 6 7 8 9 10 11 public Toolbar initToolbar (int toolbarId, int title) { AppCompatActivity mAppCompatActivity = (AppCompatActivity) mActivity; Toolbar toolbar = (Toolbar) mAppCompatActivity.findViewById(toolbarId); mAppCompatActivity.setSupportActionBar(toolbar); ActionBar actionBar = mAppCompatActivity.getSupportActionBar(); if (actionBar != null ) { actionBar.setDisplayHomeAsUpEnabled(false ); actionBar.setDisplayShowTitleEnabled(false ); } return toolbar; }
好的,这样标题就没有错乱了,然后又来了新的“需求”:Fragment如何让Toolbar菜单生效?
在activity中:
1 2 3 4 5 @Override public boolean onCreateOptionsMenu (Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return super .onCreateOptionsMenu(menu); }
在Fragment中:
1 2 3 4 5 @Override public void onCreateOptionsMenu (Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.pictrue_list, menu); super .onCreateOptionsMenu(menu,inflater); }
两者不同的地方在于: 1、一个有返回值(boolean类型),一个没有返回值。 2、Fragment中onCreateOptionsMenu的参数多了一个MenuInflater
想让Fragment中的onCreateOptionsMenu生效必须先调用setHasOptionsMenu方法,否则Toolbar没有菜单。
1 2 3 4 5 6 7 8 9 public class BaseFragment extends Fragment { Activity mActivity; @Override public void onViewCreated (View view, Bundle savedInstanceState) { super .onViewCreated(view, savedInstanceState); mActivity = getActivity(); setHasOptionsMenu(true ); } }
setHasOptionsMenu方法源码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public void setHasOptionsMenu (boolean hasMenu) { if (mHasMenu != hasMenu) { mHasMenu = hasMenu; if (isAdded() && !isHidden()) { mHost.onSupportInvalidateOptionsMenu(); } } }
<
单独使用而不与ActionBar进行关联 在Android Toolbar 一文中介绍了单独使用而不与ActionBar进行关联,直接使用ToolBar的inflateMenu方法,Menu的事件也是独立的,需要通过设置ToolBar的setOnMenuItemClickListener来实现,这样做就不会发生标题错乱。