最近在研究關(guān)于MaterialDesign系類的內(nèi)容驼鞭,在研究Toolbar和NavigationView的時(shí)候,都使用到menu的內(nèi)容揪罕。感覺(jué)自己不是很理解讹堤,可以說(shuō)就是不知道吆鹤,只會(huì)簡(jiǎn)單的寫一個(gè)menu其他的什么都不會(huì)了。所以總結(jié)一下洲守,希望對(duì)大家有幫助R晌瘛!岖沛!
本文會(huì)講解的知識(shí)點(diǎn)
- menu的使用
- menu的屬性說(shuō)明
- menu的使用注意事項(xiàng)
1. menu的使用
首先說(shuō)明一下menu的存放位置暑始,在創(chuàng)建項(xiàng)目的時(shí)候搭独,是沒(méi)有menu文件夾的婴削,所以這里你要自己創(chuàng)建一個(gè)menu文件夾,然后新建一個(gè)menu文件牙肝。具體位置看下面這張圖就可以了(因?yàn)檫@張圖設(shè)置了相應(yīng)的樣式唉俗,所以彈出來(lái)的popup有一個(gè)背景色)!
下面我們來(lái)介紹關(guān)于menu文件怎么寫配椭,以及各個(gè)屬性的含義
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/menu_search"
android:icon="@drawable/ic_search_black_24dp"
android:title="搜索"
app:actionViewClass="android.widget.SearchView"
app:showAsAction="ifRoom" />
<item
android:id="@+id/menu_cycling"
android:icon="@mipmap/ic_directions_bike_white_24dp"
android:title="去知乎的Toolbar"
app:showAsAction="ifRoom" />
<item
android:id="@+id/menu_other"
android:title="去網(wǎng)易云音樂(lè)的ToolBar"
app:showAsAction="never" />
<item
android:id="@+id/menu_more"
android:title="更多">
<menu>
<item
android:id="@+id/menu_more1"
android:title="更多1" />
<item
android:id="@+id/menu_more2"
android:title="更多2" />
<item
android:id="@+id/menu_more3"
android:title="更多3" />
</menu>
</item>
</menu>
這是一個(gè)比較復(fù)雜的menu文件了虫溜,對(duì)于一般的menu不會(huì)有下面更多的那個(gè)item。還是先看一下效果吧!
看了效果之后股缸,我們就很好理解其中的屬性了衡楞,這里先解釋一下相應(yīng)的menu標(biāo)簽的屬性值:
2. menu的屬性說(shuō)明
2.1 item的屬性說(shuō)明
這里面的屬性很多,但是個(gè)人覺(jué)得有很多用不上敦姻,列出來(lái)的都是一些常用的屬性瘾境。
- android:id 控件的ID
- android:icon 空間的圖標(biāo)(這里如果顯示在Toolbar上面歧杏,會(huì)顯示圖片,在溢出菜單里面的話會(huì)只顯示文字)
- android:title 顯示的標(biāo)題(也就是條目的內(nèi)容)
- app:actionViewClass 引入一個(gè)View(這個(gè)是在實(shí)現(xiàn)搜索的時(shí)候用到的)
- app:showAsAction 顯示方式
- ifRoom 如果有空間的話,會(huì)顯示在ToolBar上,當(dāng)空間不足的時(shí)候會(huì)顯示在列表中
- always 一直顯示在ToolBar上(如果沒(méi)有空間的話迷守,還是會(huì)顯示在列表中犬绒,按先后順序排列的)
- collapseActionView (一般要配合ifRoom一起使用)聲明這個(gè)操作視窗應(yīng)該被折疊到一個(gè)按鈕中,當(dāng)用戶選擇這個(gè)按鈕時(shí),這個(gè)操作視窗展開。這個(gè)屬性主要是實(shí)現(xiàn)自意義溢出菜單的兑凿】Γ可以在它的里面設(shè)置一些item從而實(shí)現(xiàn)溢出菜單(這個(gè)自定義的溢出菜單和默認(rèn)的溢出菜單唯一的區(qū)別就是它可以顯示圖標(biāo))
- never 不會(huì)顯示在Toolbar上面,會(huì)顯示在列列表中
- withText 表示顯示的時(shí)候如果空間足夠礼华,會(huì)顯示menu的title咐鹤。但是我試了試沒(méi)看到,還請(qǐng)知道的大神告知一聲卓嫂!
- android:titleCondensed 當(dāng)你設(shè)置的內(nèi)容過(guò)長(zhǎng)的時(shí)候慷暂,可以使用這個(gè)屬性進(jìn)行簡(jiǎn)短的說(shuō)明
- android:onClick 和View的onClick方法類似,設(shè)置一個(gè)點(diǎn)擊事件
- android:checkable 菜單是否可以復(fù)選晨雳,如果可以復(fù)選的話設(shè)置成true
- android:checked 菜單是否可以被選中行瑞,如果可以被選中的話設(shè)置成true
- android:visible 菜單是否顯示
- android:enabled 菜單項(xiàng)目是否可用,如果可用為true餐禁。主要是用在自定義溢出菜單的時(shí)候血久,是否可以進(jìn)行相應(yīng)的相應(yīng)。
- android:orderInCategory 菜單的優(yōu)先級(jí)帮非,整數(shù)類型氧吐,數(shù)字越小越靠前
2.2 group的屬性說(shuō)明
主要是一個(gè)組的屬性,和RadioGroup的樣式類似末盔,主要是實(shí)現(xiàn)復(fù)選的筑舅!里面的一些屬性和上面是類似的,這里主要說(shuō)明一個(gè)屬性
- android:checkableBeharior 設(shè)置復(fù)選行為的類型
- none 沒(méi)有可復(fù)選性
- all 組內(nèi)的所有的項(xiàng)目都可以被復(fù)選(使用復(fù)選框)
- single 僅有一個(gè)項(xiàng)目能夠被復(fù)選(使用單選按鈕)
下面是關(guān)于group標(biāo)簽的使用
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/app_bar_search"
android:icon="@drawable/ic_search_black_24dp"
android:title="Search"
app:actionViewClass="android.widget.SearchView"
app:showAsAction="always" />
<item
android:id="@+id/menu_delete"
android:icon="@mipmap/ic_delete"
android:title="刪除"
app:showAsAction="always|collapseActionView">
<menu>
<group android:checkableBehavior="all">
<item android:title="group1" />
<item android:title="group2" />
<item android:title="group3" />
</group>
</menu>
</item>
<item
android:id="@+id/menu_setting"
android:icon="@mipmap/ic_delete"
android:title="設(shè)置"
app:showAsAction="ifRoom" />
<item
android:id="@+id/menu_other"
android:icon="@mipmap/ic_delete"
android:title="不知道什么"
app:showAsAction="ifRoom" />
</menu>
這里就是通過(guò)自定義溢出菜單展示的group陨舱,具體效果看下面這張圖
設(shè)置menu二級(jí)菜單的時(shí)候(無(wú)論是自定義還是系統(tǒng)的)翠拣,前一級(jí)標(biāo)簽的文字顏色是黑色的,這個(gè)目前還沒(méi)有找到好的解決方案游盲,希望知道的給留個(gè)言N竽埂!益缎!謝謝
3. menu的使用注意事項(xiàng)
這里我主要像說(shuō)明一下我在開發(fā)中遇到的關(guān)于menu的一些問(wèn)題
- Fragment中怎么顯示menu谜慌?
- Activity和Fragment同時(shí)使用menu會(huì)怎樣顯示?
- Activity和Fragment同時(shí)處理點(diǎn)擊事件怎么相應(yīng)莺奔?
- menu的怎么動(dòng)態(tài)改變欣范?
- 多個(gè)Activity同時(shí)使用一個(gè)menu怎么簡(jiǎn)化操作?
這些問(wèn)題,在平時(shí)的開發(fā)中恼琼,相信很多人都不會(huì)注意到杖刷!所以這里有必要和大家分享一下相關(guān)的內(nèi)容。
3.1 Fragment中怎么顯示menu驳癌?
Fragment中顯示menu文件和Activity中是類似的滑燃,但是必須在掛在View之前添加
setHasOptionsMenu(true);
這句代碼(基本上都是加載onCreat()上面),否則顯示不出來(lái)的颓鲜。表窘。。
public class Main1Fragment extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_main1, container, false);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_main_fragment1, menu);
}
}
上面這段代碼就是Fragment中顯示menu的方法甜滨!
3.2 Activity和Fragment同時(shí)使用menu會(huì)怎樣顯示乐严?
是不是覺(jué)得很奇怪的問(wèn)題,你的答案是什么衣摩?是不是變得模棱兩可了昂验,其實(shí)有的面試官很關(guān)注這些細(xì)節(jié)。答案就是疊加顯示艾扮,怎么個(gè)疊加顯示呢既琴?一個(gè)簡(jiǎn)單的說(shuō)明,你在Activity中添加了一個(gè)設(shè)置的menu條目泡嘴,如果你在Fragment中也寫了一個(gè)甫恩,那么menu上會(huì)新增一個(gè)Fragment的menu文件。
3.3 Activity和Fragment同時(shí)處理點(diǎn)擊事件怎么相應(yīng)酌予?
有的人可能會(huì)問(wèn)了磺箕,那點(diǎn)擊事件怎么處理呢?其實(shí)處理起來(lái)很簡(jiǎn)單抛虫,就是在
onOptionsItemSelected
處理相應(yīng)的點(diǎn)擊事件松靡。但是有一個(gè)點(diǎn)需要注意,就是Activity的onOptionsItemSelected
方法的返回值建椰!默認(rèn)的情況下應(yīng)該返回super.onOptionsItemSelected(item)
這個(gè)雕欺,防止處理了事件之后,F(xiàn)ragment收不到相應(yīng)的點(diǎn)擊事件广凸!
- Activity的
onOptionsItemSelected
方法:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_setting:
Log.e(TAG, "onOptionsItemSelected: setting");
return true;
case R.id.menu_other:
Log.e(TAG, "onOptionsItemSelected: other" );
return true;
default:
return super.onOptionsItemSelected(item);
}
}
- Fragment的
onOptionsItemSelected
方法:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.fragment1:
Log.e(TAG, "onOptionsItemSelected: fragment1" );
return true;
case R.id.fragment2:
Log.e(TAG, "onOptionsItemSelected: fragment2" );
return true;
default:
return super.onOptionsItemSelected(item);
}
}
這樣所有的點(diǎn)擊事件就能得到相應(yīng)的響應(yīng)了阅茶。
3.4 menu的怎么動(dòng)態(tài)改變蛛枚?
有的人可能說(shuō)動(dòng)態(tài)的刷新了menu但是卻沒(méi)有成功谅海,其實(shí)是沒(méi)有調(diào)用
invalidateOptionsMenu();
通知menu刷新的方法造成的。下面我們來(lái)看看menu刷新的代碼:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.fragment1:
Log.e(TAG, "onOptionsItemSelected: fragment1");
isRefeesh = true;
getActivity().invalidateOptionsMenu();
return true;
case R.id.fragment2:
Log.e(TAG, "onOptionsItemSelected: fragment2");
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void onPrepareOptionsMenu(Menu menu) {
MenuItem item = menu.findItem(R.id.fragment1);
if (isRefeesh) {
item.setTitle("刷新后的fragment1");
} else {
item.setTitle(item.getTitle());
}
}
這里說(shuō)一下相應(yīng)的邏輯蹦浦,當(dāng)調(diào)用invalidateOptionsMenu();
的時(shí)候會(huì)重走onPrepareOptionsMenu
這個(gè)方法扭吁,這里我用了一個(gè)標(biāo)識(shí)去標(biāo)記是否刷新,為什么會(huì)有這個(gè)標(biāo)識(shí)呢?因?yàn)?code>onPrepareOptionsMenu準(zhǔn)備menu的時(shí)候調(diào)用侥袜,所以剛一進(jìn)來(lái)的時(shí)候就會(huì)被調(diào)用一次蝌诡,點(diǎn)擊后還會(huì)調(diào)用一次。
3.5 多個(gè)Activity同時(shí)使用一個(gè)menu怎么簡(jiǎn)化操作枫吧?
這個(gè)相當(dāng)于繼承的關(guān)系浦旱。其實(shí)這個(gè)問(wèn)題也是相應(yīng)的疊加問(wèn)題,只要你記住menu是可以疊加的就可以九杂。只要在你的
onCreateOptionsMenu
方法中加載父類的menu就可以了颁湖,像下面面這樣!
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);//調(diào)用這一句保證父類的菜單項(xiàng)可以正常加載
getMenuInflater().inflate(R.menu.menu_main_fragment,menu);//加載子類自己的菜單項(xiàng)
return true;
}
基本上關(guān)于menu的使用就這些了例隆,總結(jié)的可能還會(huì)有不到位的地方甥捺,如果你還有關(guān)于menu的使用問(wèn)題,可以給我留言镀层。