我们经常会有这样的需求,在切换Fragment或者点击某个按钮后动态更新Toolbar上Menu项.但是onCreateOptionsMenu方法只在创建Activity的时候调用一次,以后就不再调用了,所以就不能在onCreateOptionsMenu中做处理了。
不过系统提供了另外的一个方法onPrepareOptionsMenu,我们可以在这个方法中做一些逻辑处理,然后在需要更新Menu的地方调用invalidateOptionsMenu方法。
效果图如下:

点击`管理专辑`按钮更换Menu,

```
<span class="fu"><span class="hljs-meta">@Override</span></span> <span class="kw"><span class="hljs-function"><span class="hljs-keyword">public</span></span></span> <span class="dt"><span class="hljs-function"><span class="hljs-keyword">boolean</span></span></span> <span class="fu"><span class="hljs-function"><span class="hljs-title">onCreateOptionsMenu</span></span></span><span class="hljs-function"><span class="hljs-params">(Menu menu)</span> </span>{ <span class="fu">getMenuInflater</span>().<span class="fu">inflate</span>(R.<span class="fu">menu</span>.<span class="fu">menu</span>, menu); <span class="kw"><span class="hljs-keyword">return</span></span> <span class="kw"><span class="hljs-keyword">super</span></span>.<span class="fu">onCreateOptionsMenu</span>(menu); }
</div>
<div class="sourceCode">
<div class="top-box hide">
</div>
```
`<span class="fu"><span class="hljs-meta">@Override</span></span>
<span class="kw"><span class="hljs-function"><span class="hljs-keyword">public</span></span></span> <span class="dt"><span class="hljs-function"><span class="hljs-keyword">boolean</span></span></span> <span class="fu"><span class="hljs-function"><span class="hljs-title">onPrepareOptionsMenu</span></span></span><span class="hljs-function"><span class="hljs-params">(Menu menu)</span> </span>{
<span class="kw"><span class="hljs-keyword">if</span></span> (mIsEditStatus) {
menu.<span class="fu">findItem</span>(R.<span class="fu">id</span>.<span class="fu">action_share</span>).<span class="fu">setVisible</span>(<span class="kw"><span class="hljs-keyword">false</span></span>);
menu.<span class="fu">findItem</span>(R.<span class="fu">id</span>.<span class="fu">action_edit</span>).<span class="fu">setVisible</span>(<span class="kw"><span class="hljs-keyword">true</span></span>);
} <span class="kw"><span class="hljs-keyword">else</span></span> {
menu.<span class="fu">findItem</span>(R.<span class="fu">id</span>.<span class="fu">action_share</span>).<span class="fu">setVisible</span>(<span class="kw"><span class="hljs-keyword">true</span></span>);
menu.<span class="fu">findItem</span>(R.<span class="fu">id</span>.<span class="fu">action_edit</span>).<span class="fu">setVisible</span>(<span class="kw"><span class="hljs-keyword">false</span></span>);
}
<span class="kw"><span class="hljs-keyword">return</span></span> <span class="kw"><span class="hljs-keyword">super</span></span>.<span class="fu">onPrepareOptionsMenu</span>(menu);
}`
另外的一个需求是在Menu中要显示图标和文字,虽然在`menu.xml`文件中配置了图标和文字,但是在有图标的情况下文字是不会显示的,即使设置 `app:showAsAction="always|withText"` 但是我在运行的时候发现并没有显示文字,处理方法是通过另外一个属性实现`app:actionLayout`.
首先menu.xml定义如下:
```
<item android:id="@+id/action_share"
android:title="分享"
android:orderInCategory="80"
android:icon="@drawable/icon_share_white"
app:showAsAction="always|withText" />
<item android:id="@+id/action_edit"
android:title=""
android:orderInCategory="60"
app:showAsAction="always"
app:actionLayout="@layout/menu_action_album_edit"
/>
" data-snippet-id="ext.be441354fd8820bfea71da7e5777101d" data-snippet-saved="false" data-codota-status="done">`<span class="kw"><span class="hljs-tag"><<span class="hljs-name">menu</span></span></span><span class="ot"><span class="hljs-tag"> <span class="hljs-attr">xmlns:android</span>=</span></span><span class="st"><span class="hljs-tag"><span class="hljs-string">"http://schemas.android.com/apk/res/android"</span></span></span>
<span class="ot"><span class="hljs-tag"> <span class="hljs-attr">xmlns:app</span>=</span></span><span class="st"><span class="hljs-tag"><span class="hljs-string">"http://schemas.android.com/apk/res-auto"</span></span></span>
<span class="ot"><span class="hljs-tag"> <span class="hljs-attr">xmlns:tools</span>=</span></span><span class="st"><span class="hljs-tag"><span class="hljs-string">"http://schemas.android.com/tools"</span></span></span>
<span class="ot"><span class="hljs-tag"> <span class="hljs-attr">tools:context</span>=</span></span><span class="st"><span class="hljs-tag"><span class="hljs-string">".album.AlbumDetailActivity"</span></span></span><span class="kw"><span class="hljs-tag">></span></span><span class="kw"><span class="hljs-tag"><<span class="hljs-name">item</span></span></span><span class="ot"><span class="hljs-tag"> <span class="hljs-attr">android:id</span>=</span></span><span class="st"><span class="hljs-tag"><span class="hljs-string">"@+id/action_share"</span></span></span>
<span class=“ot”><span class=“hljs-tag”> <span class=“hljs-attr”>android:title</span>=</span></span><span class=“st”><span class=“hljs-tag”><span class=“hljs-string”>“分享”</span></span></span> <span class=“ot”><span class=“hljs-tag”> <span class=“hljs-attr”>android:orderInCategory</span>=</span></span><span class=“st”><span class=“hljs-tag”><span class=“hljs-string”>“80”</span></span></span> <span class=“ot”><span class=“hljs-tag”> <span class=“hljs-attr”>android:icon</span>=</span></span><span class=“st”><span class=“hljs-tag”><span class=“hljs-string”>"@drawable/icon_share_white"</span></span></span> <span class=“ot”><span class=“hljs-tag”> <span class=“hljs-attr”>app:showAsAction</span>=</span></span><span class=“st”><span class=“hljs-tag”><span class=“hljs-string”>“always|withText”</span></span></span> <span class=“kw”><span class=“hljs-tag”>/></span></span>
<span class="kw"><span class="hljs-tag"><<span class="hljs-name">item</span></span></span><span class="ot"><span class="hljs-tag"> <span class="hljs-attr">android:id</span>=</span></span><span class="st"><span class="hljs-tag"><span class="hljs-string">"@+id/action_edit"</span></span></span>
<span class=“ot”><span class=“hljs-tag”> <span class=“hljs-attr”>android:title</span>=</span></span><span class=“st”><span class=“hljs-tag”><span class=“hljs-string”>""</span></span></span> <span class=“ot”><span class=“hljs-tag”> <span class=“hljs-attr”>android:orderInCategory</span>=</span></span><span class=“st”><span class=“hljs-tag”><span class=“hljs-string”>“60”</span></span></span> <span class=“ot”><span class=“hljs-tag”> <span class=“hljs-attr”>app:showAsAction</span>=</span></span><span class=“st”><span class=“hljs-tag”><span class=“hljs-string”>“always”</span></span></span> <span class=“ot”><span class=“hljs-tag”> <span class=“hljs-attr”>app:actionLayout</span>=</span></span><span class=“st”><span class=“hljs-tag”><span class=“hljs-string”>"@layout/menu_action_album_edit"</span></span></span> <span class=“kw”><span class=“hljs-tag”>/></span></span>
<span class=“kw”><span class=“hljs-tag”></<span class=“hljs-name”>menu</span>></span></span>`
</div>
`app:actionLayout`指向了一个布局,可以在这个布局中定义你想要的控件。我的定义是这样的。
`menu_action_album_edit.xml`
<div class="sourceCode">
<div class="top-box hide">
</div>
```
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dip"
android:paddingRight="10dip"
android:gravity="center"
android:text="@string/app_edit"
android:drawableLeft="@drawable/album_edit_white"
android:textColor="@color/white"
android:clickable="true" />" data-snippet-id="ext.67853aa79917befa6351c9258124c9c9" data-snippet-saved="false" data-codota-status="done">`<span class="kw"><span class="hljs-meta"><?xml</span></span><span class="hljs-meta"> version="1.0" encoding="utf-8"</span><span class="kw"><span class="hljs-meta">?></span></span>
<span class="kw"><span class="hljs-tag"><<span class="hljs-name">TextView</span></span></span><span class="ot"><span class="hljs-tag"> <span class="hljs-attr">xmlns:android</span>=</span></span><span class="st"><span class="hljs-tag"><span class="hljs-string">"http://schemas.android.com/apk/res/android"</span></span></span>
<span class="ot"><span class="hljs-tag"> <span class="hljs-attr">android:layout_width</span>=</span></span><span class="st"><span class="hljs-tag"><span class="hljs-string">"wrap_content"</span></span></span>
<span class="ot"><span class="hljs-tag"> <span class="hljs-attr">android:layout_height</span>=</span></span><span class="st"><span class="hljs-tag"><span class="hljs-string">"wrap_content"</span></span></span>
<span class="ot"><span class="hljs-tag"> <span class="hljs-attr">android:paddingLeft</span>=</span></span><span class="st"><span class="hljs-tag"><span class="hljs-string">"10dip"</span></span></span>
<span class="ot"><span class="hljs-tag"> <span class="hljs-attr">android:paddingRight</span>=</span></span><span class="st"><span class="hljs-tag"><span class="hljs-string">"10dip"</span></span></span>
<span class="ot"><span class="hljs-tag"> <span class="hljs-attr">android:gravity</span>=</span></span><span class="st"><span class="hljs-tag"><span class="hljs-string">"center"</span></span></span>
<span class="ot"><span class="hljs-tag"> <span class="hljs-attr">android:text</span>=</span></span><span class="st"><span class="hljs-tag"><span class="hljs-string">"@string/app_edit"</span></span></span>
<span class="ot"><span class="hljs-tag"> <span class="hljs-attr">android:drawableLeft</span>=</span></span><span class="st"><span class="hljs-tag"><span class="hljs-string">"@drawable/album_edit_white"</span></span></span>
<span class="ot"><span class="hljs-tag"> <span class="hljs-attr">android:textColor</span>=</span></span><span class="st"><span class="hljs-tag"><span class="hljs-string">"@color/white"</span></span></span>
<span class="ot"><span class="hljs-tag"> <span class="hljs-attr">android:clickable</span>=</span></span><span class="st"><span class="hljs-tag"><span class="hljs-string">"true"</span></span></span> <span class="kw"><span class="hljs-tag">/></span></span>`
`android:drawableLeft`中指定你的图标。
然后还要在onCreateOptionsMenu中重写一下Menu的点击事件,现在onCreateOptionsMenu方法是这样的:
```
`<span class=“fu”><span class=“hljs-meta”>@Override</span></span> <span class=“kw”><span class=“hljs-function”><span class=“hljs-keyword”>public</span></span></span> <span class=“dt”><span class=“hljs-function”><span class=“hljs-keyword”>boolean</span></span></span> <span class=“fu”><span class=“hljs-function”><span class=“hljs-title”>onCreateOptionsMenu</span></span></span><span class=“hljs-function”><span class=“hljs-params”>(Menu menu)</span> </span>{ <span class=“fu”>getMenuInflater</span>().<span class=“fu”>inflate</span>(R.<span class=“fu”>menu</span>.<span class=“fu”>menu</span>, menu); <span class=“dt”><span class=“hljs-keyword”>final</span></span> MenuItem item = menu.<span class=“fu”>findItem</span>(R.<span class=“fu”>id</span>.<span class=“fu”>action_edit</span>); item.<span class=“fu”>getActionView</span>().<span class=“fu”>setOnClickListener</span>(<span class=“kw”><span class=“hljs-keyword”>new</span></span> View.<span class=“fu”>OnClickListener</span>() { <span class=“fu”><span class=“hljs-meta”>@Override</span></span> <span class=“kw”><span class=“hljs-function”><span class=“hljs-keyword”>public</span></span></span> <span class=“dt”><span class=“hljs-function”><span class=“hljs-keyword”>void</span></span></span> <span class=“fu”><span class=“hljs-function”><span class=“hljs-title”>onClick</span></span></span><span class=“hljs-function”><span class=“hljs-params”>(View v)</span> </span>{ <span class=“fu”>onOptionsItemSelected</span>(item); } });
<span class="kw"><span class="hljs-keyword">return</span></span> <span class="kw"><span class="hljs-keyword">super</span></span>.<span class="fu">onCreateOptionsMenu</span>(menu);
}`
</div>
然后像普通的Menu item一样在onOptionsItemSelected中处理点击事件就可以了。
</div>
<div class="clear">
</div>
<div id="blog_post_info_block">
</div>
💬 评论