1.1 Menu 菜單
【
Menu 菜單
1. OptionsMenu 選項菜單
特點: 當通過點擊menu鍵或者3.0以上的手機上,點擊右上方的三個點,出現的列表,都是有OptionMenu對象進行控制
2. ContextMenu上下文菜單
特點:當長按指定控件後,在屏幕中心彈出列表對話框
3. PopupMenu 浮動菜單
特點:通過指定控件指定監聽,觸發顯示,可以讓菜單列表顯示在指定控件的下方
】
1.1.1 概述
【
從Android 3.0開始,Android不要求手機設備上必須提供MENU按鍵。因此Android推薦使用ActionBar來代替Menu
】
1.1.2 菜單的創建
【
1、通過代碼創建
2、使用xml資源文件創建菜單(res/menu目錄下)(建議使用,重點掌握)
】
1.1.3 菜單的分類
【
Options Menu 選項菜單
Context Menu 上下文菜單
Popup Menu 浮動菜單
】
1.1.4 在XML中定義Menu文件
【
位置:res/menu目錄下
<menu>:代表菜單資源
<item>:菜單項
android:id // 菜單項的id
android:icon // 菜單項的圖標
android:title // 菜單項的標題
android:orderInCategory // 排序
android:showAsAction // 在ActionBar上的顯示參數(API 11)
never:不將MenuItem顯示在ActionBar上(是默認值)
always:總是將該MenuItem顯示在ActionBar上
ifRoom:當AcitonBar上有空間時將該MenuItem顯示在ActionBar上,沒有空間就放入溢出菜單中
withText:將該MenuItem顯示在ActionBar上,並顯示該菜單項的文本
顯示自定義ActionBar的View,需要和actionViewClass這組參數結合使用(API14)
<group>:菜單組
二級菜單(子菜單的創建)
概念:在menu Item中嵌套menu元素,可以實現多級菜單,嵌套的菜單叫做子菜單,一般只會使用二級菜單,如果菜單層次太深,會嚴重影響用戶體驗。
二級可選菜單
android:checkableBehavior
有三個屬性值可選
all(多選)
single(單選)
none(不可選)
】
1.1.5 選項菜單
【
使用步驟
初始化選項菜單:onCreateOptionsMenu(Menu menu)
爲菜單項設置監聽器:onOptionsItemSelected(MenuItem item)
OptionsMenu的使用方式:
方式一:純代碼處理(官方並不是特別推薦)
方式二:xml文件+代碼(官方推薦方式)
通過xml文件+代碼實現Options Menu的顯示
Xml文件:負責設置菜單列表中總共要顯示哪些數據選項,以及這些選項的顯示特點
代碼: 負責處理加載xml文件,並處理點擊事件
關於xml文件的處理:
1. 在res文件夾內容準備一個menu文件夾,所有控制菜單顯示的xml文件均被存於此處
2. 在menu文件夾中創建一個xml文件,讓該文件以menu標籤作爲根標籤
3. 在menu標籤之間添加item標籤,每一個item標籤代表一個菜單選項
4. 處理item標籤中的屬性
代碼實現:
<?xml version="1.0"encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<!--
android:id 用於設置item的id,即唯一標識,用於稍後的點擊判斷
android:title 用於設置標題
android:orderInCategory 用於設置item選項在菜單列表中的排列順序
屬性值越小,排列順序越靠前,
如果屬性值相同,哪個item的代碼在前面,哪個item就排名靠前
android:icon 用於設置圖標。注意:如果item是顯示在菜單列表中,那麼
圖標永遠不顯示
android:showAsAction android3.0 以後纔出的屬性
用於設置item在標題欄上的顯示特點
可選屬性值:
never 該選項永遠顯示在菜單列表中
ifRoom 如果標題欄上有剩餘空間,就顯示在標題欄上,如果沒有,就顯示在菜單列表中
always 該選項永遠直接顯示在標題欄上
withText 讓圖標和文字同時顯示
-->
<item
android:id="@+id/item1"
android:title="菜單項一"
android:orderInCategory="3000"
android:showAsAction="always|withText"
android:icon="@drawable/ic_launcher"/>
<item
android:id="@+id/item2"
android:title="菜單項二"
android:orderInCategory="10"
android:showAsAction="ifRoom"
android:icon="@drawable/ic_launcher"/>
<item
android:id="@+id/item3"
android:orderInCategory="20"
android:title="菜單項三"
android:icon="@drawable/ic_launcher"/>
</menu>
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
/*
* 重寫onCreateOptionsMenu方法,在此方法中加載xml文件參數:代表要顯示的菜單對象
*
* 返回值:true 顯示菜單, false 不顯示菜單
*/
@Override
public boolean onCreateOptionsMenu(Menu menu){
// TODOAuto-generated method stub
/*
* 將my.xml文件中的所有item菜單選項添加到參數二指定的menu對象中顯示
*/
getMenuInflater().inflate(R.menu.my_menu, menu);
//通過代碼添加菜單選項
/*
* 1. 該菜單選項所在組的groupId
* 2. 該菜單的唯一標識,id屬性的值
* 3. 控制排列順序,作用等同於orderInCategory屬性
* 4:選項上要顯示的文字標題
* */
menu.add(0, 1, 20, "代碼添加menu");
return true;
}
//重寫此方法,獲取菜單項的點擊事件,參數代表被點擊的菜單選項
@Override
public boolean onOptionsItemSelected(MenuItemitem) {
// TODOAuto-generated method stub
Toast.makeText(this,item.getTitle()+String.valueOf(item.getItemId()), Toast.LENGTH_SHORT).show();
//區分被點擊的item
switch (item.getItemId()){
caseR.id.item1:
break;
caseR.id.item2:
break;
caseR.id.item3:
break;
}
return super.onOptionsItemSelected(item);
}
}
】
1.1.5.1 示例代碼
【
<?xml version="1.0"encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/menu1"
android:orderInCategory="100"
android:showAsAction="never"
android:title="選項菜單1"/>
<item
android:id="@+id/menu2"
android:orderInCategory="100"
android:showAsAction="never"
android:title="選項菜單2"/>
<item
android:id="@+id/menu3"
android:orderInCategory="100"
android:showAsAction="never"
android:title="選項菜單3"/>
<!--選項菜單可分組 -->
<group android:id="@+id/menu_group1">
<item
android:id="@+id/menu4"
android:orderInCategory="100"
android:showAsAction="never"
android:title="組1選項菜單1"/>
<item
android:id="@+id/menu5"
android:orderInCategory="100"
android:showAsAction="never"
android:title="組1選項菜單2"/>
</group>
<!--在XML添加具有子選項的菜單 -->
<item
android:id="@+id/con_son_menu"
android:title="點擊出子菜單">
<menu>
<!-- 樣式出現選擇樣式 -->
<group android:checkableBehavior="all" >
<item
android:checked="true"
android:id="@+id/con_son_menu_1"
android:title="子菜單1"/>
<item
android:id="@+id/con_son_menu_2"
android:title="子菜單2"/>
</group>
</menu>
</item>
</menu>
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// TODOAuto-generated method stub
//佈局xml配置加載
getMenuInflater().inflate(R.menu.my_menu, menu);
//代碼添加菜單項
menu.add(2, 2, 150, "組2代碼項1");
menu.add(2, 3, 150, "組2代碼項2");
/**
* 可以根據組ID決定組中的菜單項是否可見或可操作
*/
menu.setGroupEnabled(2,false);
/**
* 通過代碼添加有子菜單項的菜單
*/
SubMenu sub = menu.addSubMenu(3, 33, 333, "代碼子菜單");
sub.add(3, 34, 333, "子1");
sub.add(3, 35, 333, "子2").setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override//boolean監聽:代表處理完監聽,是否還要進行額外操作
publicboolean onMenuItemClick(MenuItemitem) {
// TODOAuto-generated method stub
Toast.makeText(MainActivity.this, "=====+"+item.getTitle()+"設置單個子菜單事件", Toast.LENGTH_SHORT).show();
returnfalse;
}
});
return true;
}
//菜單列表item的點擊事件,參數代表被點擊的item菜單選項
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODOAuto-generated method stub
switch(item.getItemId()) {
case 34:
Toast.makeText(MainActivity.this, "點擊了子菜單中的子選項1", Toast.LENGTH_SHORT).show();
break;
case 35:
Toast.makeText(MainActivity.this, "點擊了子菜單中的子選項2", Toast.LENGTH_SHORT).show();
break;
}
return super.onOptionsItemSelected(item);
}
}
】
1.1.6 上下文菜單
【
使用步驟
初始化上下文菜單:onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo)
爲指定控件註冊上下文菜單:registerForContextMenu(Viewview)
爲菜單項設置監聽器:onContextItemSelected(MenuItemitem)
特點:當長按指定控件的時候顯示的菜單列表
位置固定顯示與屏幕中心
使用步驟:
大體步驟與OptionsMenu 基本一致
1. 通過menu文件夾中的xml文件定義菜單列表中要顯示的內容
2. 重寫onCreateContextMenu方法,在該方法中通過
3. 重寫onContextItemSelected方法獲取菜單選項被點擊的監聽事件
4. 在頁面的onCreate方法中通過registerForContextMenu方法的參數指定長按哪個控件對象顯示菜單
當registerForContextMenu方法中傳遞的是一個listview對象時,ContextMenu是針對列表中每個item進行設置
在onContextItemSelected方法中可以通過以下方式獲取別長按的item在listview中對應的position位置
//獲取被點擊的菜單選項對應的菜單信息封裝對象
AdapterContextMenuInfo aci = (AdapterContextMenuInfo) item.getMenuInfo();
//通過菜單信息封裝對象獲取被點擊的item的位置
int position = aci.position;
】
1.1.6.1 示例代碼
【
<?xml version="1.0"encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/list_item1"
android:title="複製"/>
<item
android:id="@+id/list_item2"
android:title="刪除"/>
<item
android:id="@+id/list_item3"
android:title="重命名"/>
</menu>
public class MainActivity extends Activity {
private TextView tv;
@Override
protected voidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv=(TextView) this.findViewById(R.id.tv);
registerForContextMenu(tv);
}
@Override
public voidonCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfomenuInfo) {
// TODO Auto-generated method stub
super.onCreateContextMenu(menu, v, menuInfo);
getMenuInflater().inflate(R.menu.main, menu);
}
}
public class TwoActivity extends Activity {
private ListView lv;
ArrayList<String>list = newArrayList<String>();
ArrayAdapter<String>adapter;
@Override
protected voidonCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_two);
lv=(ListView) this.findViewById(R.id.listview1);
for(inti=0;i<10;i++){
list.add("item"+i);
}
adapter = newArrayAdapter<>(this,android.R.layout.simple_list_item_1, list);
lv.setAdapter(adapter);
registerForContextMenu(lv);
}
@Override
public voidonCreateContextMenu(ContextMenu menu, View v, //此v是傳遞過來的對象
ContextMenuInfomenuInfo) {
// TODO Auto-generated method stub
super.onCreateContextMenu(menu, v, menuInfo);
getMenuInflater().inflate(R.menu.list_menu, menu);
v.setBackgroundColor(Color.RED);
}
@Override
public booleanonContextItemSelected(MenuItem item) {
// TODO Auto-generated method stub
AdapterContextMenuInfoaci=(AdapterContextMenuInfo)item.getMenuInfo();
final intposition = aci.position;
switch (item.getItemId()) {
case R.id.list_item1: //複製
list.add(list.get(position));
adapter.notifyDataSetChanged();
break;
case R.id.list_item2: //刪除
list.remove(position);
adapter.notifyDataSetChanged();
break;
case R.id.list_item3: //重命名
Viewv = View.inflate(this,R.layout.custom, null);
final AlertDialog dialog = new AlertDialog.Builder(this)
.setView(v)
.show();
final EditText ed_name =(EditText)v.findViewById(R.id.ed_name);
Buttonbtn_ok = (Button) v.findViewById(R.id.btn_ok);
btn_ok.setOnClickListener(new OnClickListener() {
@Override
public voidonClick(View v) {
// TODO Auto-generated method stub
list.set(position, ed_name.getText().toString());
adapter.notifyDataSetChanged();
dialog.dismiss();
}
});
break;
}
return super.onContextItemSelected(item);
}
@Override
public voidonContextMenuClosed(Menu menu) {
// TODO Auto-generated method stub
super.onContextMenuClosed(menu);
lv.setBackgroundColor(Color.WHITE);
}
}
】
1.1.7 浮動菜單
【
使用步驟
創建浮動菜單對象:PopupMenu popupMenu = newPopupMenu(this, btn_show_popupmenu);
參數1:上下文環境
參數2:需要綁定浮動菜單的控件id
將菜單文件加載到內存中:getMenuInflater().inflate(R.menu.popup_menu,popupMenu.getMenu());
爲菜單項設置監聽器:popupMenu.setOnMenuItemClickListener(OnMenuItemClickListener)
顯示菜單:popupMenu.show();
PopupMenu浮動菜單
特點:
1. 可以指定任意控件通過任意方式觸發浮動菜單的顯示
2. 可以顯示在指定控件的下方
使用方式:
1. 獲取控件對象,設置任意的監聽,如設置tv的點擊事件
代表是要在tv被點擊時顯示Popup Menu
//1.初始化popupmenu對象
/*
* 參數2:默認情況下是讓pm稍後再顯示的時候,可以顯示在該控件的下方
* 但是當該控件下方沒有足夠的控件的時候,就讓pm顯示在該控件的上方
* */
PopupMenu pm = newPopupMenu(PopupMenuActivity.this,tv);
/*
* 3參的構造方法的參數3:用於指定pm與控件的對齊方式
* 此方法必須確保在 19版本,即4.4.2版本以上才能生效
* */
// PopupMenupm = new PopupMenu(PopupMenuActivity.this, tv, Gravity.RIGHT);
2. 向popupmenu對象中添加要顯示的菜單選項
//添加方式一:
// getMenuInflater().inflate(R.menu.popup_menu,pm.getMenu());
//添加方式二
pm.inflate(R.menu.popup_menu);
3. 通過show方法顯示popupmenu對象
pm.show();
設置popupmenu中菜單選項的點擊事件:
//獲取pm菜單選項的點擊事件
pm.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
// TODO Auto-generated method stub
Toast.makeText(PopupMenuActivity.this, item.getTitle(), Toast.LENGTH_SHORT).show();
return false;
}
});
PopupWindow的使用:
浮動窗口, 特點:效果上是一個可以自定義顯示及顯示位置的對話框
使用方式:
//1.初始化對象
/*
* 1. 用於指定pw中要顯示View對象
* 2,3. 用於指定pw顯示時的寬高
* */
View vv= View.inflate(PopupWindowActivity.this, R.layout.custom, null);
PopupWindow pw = new PopupWindow(vv, 400, 400);
//設置pw中的控件能夠獲取焦點
pw.setFocusable(true);
//設置可以通過點擊pw外部關閉pw,但是生效的前提
//是必須給pw設置了背景才行
//設置pw的默認背景,即如果custom佈局中沒有指定背景的話,就顯示此背景
pw.setBackgroundDrawable(getResources().getDrawable(R.drawable.ic_launcher));
pw.setOutsideTouchable(true);
//3.通過show**方法顯示
// pw.showAsDropDown(tv,50, 50);
/*
* 1. 通過參數一指定的控件尋找該控件的父控件
* 以父控件的範圍爲基準
* 2. gravity 居中,右下等位置
* 3,4. 水平和垂直方向的偏移量
*
* */
pw.showAtLocation(tv, Gravity.CENTER, 0, 0);
】
1.1.8 擴展:PopupWindow(浮動窗口)
【
基本使用步驟
構造方法:PopupWindow(View contentView, intwidth, int height)
參數1:contentView,浮動窗口中顯示的內容
參數2:width,浮動窗口的寬度
參數3:height,浮動窗口的高度
顯示浮動窗口:showAsDropDown(Viewanchor, int xoff, int yoff)
參數1:anchor,浮動窗口出現在指定控件的下方
參數2:xoff,在X軸上的偏移量
參數3:yoff,在Y軸上的偏移量
隱藏浮動窗口:dismiss()
顯示帶列表的浮動窗口
創建ListView對象
setAdapter(ListAdapter):設置列表適配器,用於填充列表數據
setOnItemClickListener(OnItemClickListener):設置列表項的監聽事件
setFocusable(true):使浮動窗口可以獲取焦點
setBackgroundDrawable(newColorDrawable()):爲解決焦點問題,這行代碼必須執行
PopupWindow 補充:
當初始化PopupWindow對象時,需要通過構造方法傳遞PopupWindow要顯示的寬高,除了直接指定寬高對應的數字之外,能不能設置成wrap_content或者match_parent??
解決方式:在需要指定寬高的位置,通過ViewGroup包內的LayoutParams的類中的靜態常量即可調用FILL_PARENT,MATCH_PARENT和WRAP_CONTENT 屬性設置了
】
1.1.8.1 示例代碼
【
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.example.day13popupmenu.popupwindow.MainActivity">
<item
android:id="@+id/pu_menu1"
android:title="pm菜單1"/>
<item
android:id="@+id/pu_menu2"
android:title="pm菜單2"/>
<item
android:id="@+id/pu_menu3"
android:title="pm菜單3"/>
<item
android:id="@+id/pu_menu4"
android:title="pm菜單4"/>
</menu>
public class MainActivity extends Activity {
private TextView tv;
@Override
protected voidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv =(TextView) this.findViewById(R.id.tv);
tv.setOnClickListener(newOnClickListener() {
@Override
public voidonClick(View v) {
// TODO Auto-generated method stub
PopupMenu pm = new PopupMenu(MainActivity.this, tv);
getMenuInflater().inflate(R.menu.main,pm.getMenu());
//pm.inflate(R.menu.main);
pm.show();
pm.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public booleanonMenuItemClick(MenuItem item) {
// TODO Auto-generated method stub
Toast.makeText(MainActivity.this, item.getTitle(), Toast.LENGTH_SHORT).show();
return false;
}
});
pm.setOnDismissListener(new OnDismissListener() {
@Override
public voidonDismiss(PopupMenu menu) {
// TODO Auto-generated method stub
Toast.makeText(MainActivity.this, "close",Toast.LENGTH_SHORT).show();
}
});
}
});
}
}
public class TwoActivity extends Activity {
private TextView tv;
@Override
protected voidonCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) this.findViewById(R.id.tv);
tv.setOnClickListener(newOnClickListener() {
@Override
public voidonClick(View v) {
View vv = View.inflate(TwoActivity.this, R.layout.custom,null);
final PopupWindow pw = newPopupWindow(vv, 300, 300);
// pw.showAsDropDown(vv,50,50);
// 設置pw能夠獲得焦點
pw.setFocusable(true);
// 設置浮動窗體,點擊旁白能夠自動消失,但是必須要設置setBackgroundDrawable才能生效
pw.setBackgroundDrawable(getResources().getDrawable(
R.drawable.ic_launcher));
pw.setOutsideTouchable(true);
pw.showAtLocation(vv,Gravity.CENTER, 0, 0);
Buttonbtn_ok = (Button) vv.findViewById(R.id.btn_ok);
final EditText ed_edit = (EditText) vv
.findViewById(R.id.ed_name);
btn_ok.setOnClickListener(new OnClickListener() {
@Override
public voidonClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(TwoActivity.this,
ed_edit.getText().toString(),
Toast.LENGTH_SHORT).show();
pw.dismiss();
}
});
}
});
}
}
】