您的位置:首页 > 移动开发 > Android开发

Android Fragment使用Toolbar

2016-01-04 14:02 447 查看
链接:http://wuxiaolong.me/2015/12/21/fragmentToolbar/


Activity使用Toolbar

一般在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
2

<include
layout="@layout/toolbar" />

Activity一般写到基类:

1
2
3
4
5
6
7
89
10
1112
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调用:

1

initToolbar("标题");


Fragment使用Toolbar

现在项目需求,每个title不一样,就不能像以上一样写一个toolbar,放在最外层。问题来了,Fragment如何使用Toolbar?像上面一样写吗?No,Fragment没有setSupportActionBar,于是Google,得到:

1
2
3
4
5
6
7
89
10
1112
13
14
15
16
17
18
19
20
2122
23
24
25
26
27
28
29
30
3132
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
23

<include
android:id="@+id/program_toolbar"
layout="@layout/toolbar" />

BaseFragment 做相应的修改:

1
2
3
4
5
6
7
89
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菜单生效?


Fragment让Toolbar菜单生效

在activity中:

1
23
4
5

@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu);
}

在Fragment中:

1
23
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
89

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
89
10
1112
13
14
15

/**
* Report that this fragment would like to participate in populating
* the options menu by receiving a call to {@link #onCreateOptionsMenu}
* and related methods.
*
* @param hasMenu If true, the fragment has menu items to contribute.
*/
public void setHasOptionsMenu(boolean hasMenu) {
if (mHasMenu != hasMenu) {
mHasMenu = hasMenu;
if (isAdded() && !isHidden()) {
mHost.onSupportInvalidateOptionsMenu();
}
}
}


单独使用而不与ActionBar进行关联

多谢@XZoomEye提示,对于Fragment使用Toolbar思维被局限了,在Android
Toolbar一文中介绍了单独使用而不与ActionBar进行关联,直接使用ToolBar的inflateMenu方法,Menu的事件也是独立的,需要通过设置ToolBar的setOnMenuItemClickListener来实现,这样做就不会发生标题错乱。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: