OptionsMenu、SubMenu、ContextMenu及PopupWindow

一、Menu:

(一)、简介:

1、Android应用中的菜单默认是隐藏的,只有当用户点击手机上的MENU键,系统才会显示菜单。这种菜单叫做选项菜单(Options Menu),也叫做系统主菜单

2、从3.0开始,Android不要求手机设备上必须提供MENU按键。因此Android推荐使用ActionBar来代替Menu。

3、创建菜单的方式:

        Android提供了两种创建菜单的方式。分别是Java代码中创建和XML菜单资源中创建菜单。

4、菜单API:

    Menu -> SubMenu -> MenuItem

    Menu -> ContextMenu -> MenuItem

   

(二)、在java代码中创建菜单:

1、创建菜单:

public MenuItem add(int titleRes);

public MenuItem add(CharSequence title);

public MenuItem add(int groupId ,  int itemId , int  order , int  titleRes);

public MenuItem add(int groupId ,  int itemId , int  order , CharSequence  title);

 

2、给菜单选项添加icon图标

public MenuItem setIcon(int iconRes);

public MenuItem setIcon(Drawable icon);

【参数解释:】

  • groupId   菜单项分组。该参数可以是负整数、正整数和0;
  • itemId      当前添加的菜单项的id。该参数与可以是负整数、正整数和0;
  • order      菜单显示顺序。该参数必须是正整数和0。按照数值升序从左到右、从上到下排列。
  • title或titleRes     菜单项的标题文字或资源id。

        如果groupId和order为0,则菜单显示顺序为菜单项的添加顺序。

 

3、关联Activity

public MenuItem setIntent(Intent intent);

【备注:】

如果设置了菜单项的单击事件,且单击事件返回true,则菜单项的关联Activity则失效。

 

4、响应菜单的单击动作:

1)、MenuItem.setOnMenuItemClickListener()

2)、Activity.onOptionsItemSelected()

3) 、Activity.onMenuItemSelected()

【说明:】

        除了设置菜单项的单击事件外,还可以使用Activity 的 回调方法来实现菜单项被选中的点击事件。

如果同时使用这三种方式,它们会起作用吗?

如果设置了单击事件,onMenuItemClick()方法返回true。则其他两个回调方法不会被调用。

而其他两个回调方法,其实是onMenuItemSelected()在调用onOptionsItemSelected()。

 

5、创建子菜单:

SubMenu  addSubMenu(final int titleRes);

SubMenu addSubMenu(final CharSequence title);

SubMenu addSubMenu(int groupId ,  int itemId , int  order , int  titleRes);

SubMenu addSubMenu(int groupId ,  int itemId , int  order , CharSequence  title);

选项菜单不支持嵌套子菜单。不能在子菜单项目下再建子菜单,否则抛出异常。

 

 

(三)、XML资源文件中定义菜单(res/menu目录下):

1、普通菜单:

 <item
        android:id="@+id/menu_about"
        android:orderInCategory="2"
        android:showAsAction="never"
        android:title="关于"/>

 

2、二级普通菜单:

 <item
        android:id="@+id/menu_group2"
        android:orderInCategory="1"
        android:showAsAction="never"
        android:title="文字颜色">
        <menu >
            <group>
                <item android:id="@+id/font_red" android:title="red" />
                <item android:id="@+id/font_green" android:title="green"></item>
                <item android:id="@+id/font_blue" android:title="blue"></item>
                <item android:id="@+id/font_yellow" android:title="yellow"></item>
            </group>
        </menu>
    </item>

 

3、二级可选项菜单:

 <item
        android:id="@+id/menu_group1"
        android:orderInCategory="1"
        android:showAsAction="never"
        android:title="文字尺寸">
        <menu >
            <!-- android:checkableBehavior 属性有三个可选值:all为多选,single为单选,none为不可选。为none时就是一个普通菜单 -->
            <group android:checkableBehavior="single">
                <item android:id="@+id/font_10" android:title="10sp"></item>
                <item android:id="@+id/font_15" android:title="15sp"></item>
                <item android:id="@+id/font_20" android:title="20sp"></item>
                <item android:id="@+id/font_25" android:title="25sp"></item>
                <item android:id="@+id/font_30" android:title="30sp"></item>
            </group>
        </menu>
    </item>

 

 

(四)、菜单操作:

            利用boolean onOptionsItemSelected(MenuItem item)回调方法。

 

核心代码如下:利用以上定义的xml菜单文件,实现通过菜单选项对文字的大小和颜色进行控制。

        @Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.font_20:
			text_main_info.setTextSize(20);
			break;
		case R.id.font_30:
			text_main_info.setTextSize(30);
			break;
		case R.id.font_red:
			text_main_info.setTextColor(Color.RED);
			break;
		case R.id.font_green:
			text_main_info.setTextColor(Color.GREEN);
			break;
		}
		return super.onOptionsItemSelected(item);
	}

 

 

二、ContextMenu

(一)、上下文菜单介绍:上下文菜单继承自android.view.Menu。

1、上下文菜单与Options Menu最大的不同在于:

 

  • Options Menu的拥有者是Activity,而上下文菜单的拥有者是Activity中的View;
  • 每个Activity有且只有一个Options Menu,它为整个Activity服务。而一个Activity往往有多个View,哪个View需要上下文菜单就通过registerForContextMenu(View view)给这个View注册上下文菜单。

 

2、生成上下文菜单是通过Activity中的onCreateContextMenu()方法:

 

  • onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo)方法很像生成Options Menu的onCreateOptionsMenu(Menu menu)方法;
  • 两者的不同在于:onCreateOptionsMenu只在用户第一次按“Menu”键时被调用,而onCreateContextMenu会在用户每一次长按注册了上下文菜单的View时被调用。

3、ContextMenu工作原理图:

4、ContextMenuInfo 有什么用呢?

当视图元素需要向上下文菜单传递一些信息,比如该View对应DB记录的id等,这就要使用ContextMenuInfo。需要传递额外信息的View需要重写getContextMenuInfo()方法,返回一个带有数据的ContextMenuInfo实现类对象。

 

Additional information regarding the creation of the context menu. For example, AdapterViews use this to pass the exact item position within the adapter that initiated the context menu.

 

ContextMenuInfo携带了注册上下文菜单控件的一些额外信息。一般用在AdaterViews(例如:Spinner 、ListView或GridView)上,

可以在ContextMenuInfo 中获取到适配器View中的position的信息

 

 

(二)、开发上下文菜单的步骤:

1、重写onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo)方法;
2、调用Activity的registerForContextMenu(View view)方法为view组件注册上下文菜单;(注册上下文菜单后,意味着用户长按该控件后显示上下文菜单)。
3、为菜单项提供响应,重写onContextItemSelected(MenuItem item)。

 

 

(三)、示例代码:

 private TextView text_main_info;

@Override
protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_main);
	text_main_info = (TextView) findViewById(R.id.text_main_info);
	this.registerForContextMenu(text_main_info);
}

@Override
public void onCreateContextMenu(ContextMenu menu, View v,
		ContextMenuInfo menuInfo) {
	super.onCreateContextMenu(menu, v, menuInfo);
	getMenuInflater().inflate(R.menu.contextmenu_main, menu);
}

@Override
public boolean onContextItemSelected(MenuItem item) {
	switch (item.getItemId()) {
	case R.id.font_20:
		text_main_info.setTextSize(20);
		break;
	case R.id.font_30:
		text_main_info.setTextSize(30);
		break;
	case R.id.font_red:
		text_main_info.setTextColor(Color.RED);
		break;
	case R.id.font_green:
		text_main_info.setTextColor(Color.GREEN);
		break;
	}
	return super.onContextItemSelected(item);
}

 

 

三、PopupWindow:

 

(一)、案例一:

2、学习目的:

  • 学习PopupWindow的基本使用方法;
  • 运用Inent属性实现返回Home界面、拨打电话、发送短信;
  • 学习菜单生命周期的回调方法:onMemeOpened();
  • 学习回调方法onKeyDown(),监听键盘按下事件。

 

3、核心代码:

 

publicclass MainActivity extends Activity {

private PopupWindow popupWindow = null;

private View popup_view = null;

 

@Override

protectedvoid onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

popup_view = getLayoutInflater().inflate(R.layout.popwindow_menu, null);

popupWindow = new PopupWindow(popup_view, LayoutParams.MATCH_PARENT,

LayoutParams.WRAP_CONTENT);

popupWindow.setBackgroundDrawable(new ColorDrawable(Color.YELLOW));

}

 

@Override

publicboolean onKeyDown(int keyCode, KeyEvent event) {

switch (keyCode) {

case KeyEvent.KEYCODE_MENU:

if (popupWindow.isShowing()) {

popupWindow.dismiss();

} else {

popupWindow.showAtLocation(popup_view, Gravity.BOTTOM, 0, 0);

 

ImageView imageView_popup_back = (ImageView) popup_view

.findViewById(R.id.imageView_popup_back);

imageView_popup_back.setOnClickListener(new OnClickListener() {

@Override

publicvoid onClick(View v) {

Intent intent = new Intent();

// intent.setAction(Intent.ACTION_MAIN);

// intent.addCategory(Intent.CATEGORY_HOME);

intent.setAction("android.intent.action.MAIN");

intent.addCategory("android.intent.category.HOME");

startActivity(intent);

}

});

 

ImageView imageView_popup_share = (ImageView) popup_view

.findViewById(R.id.imageView_popup_share);

imageView_popup_share.setOnClickListener(new OnClickListener() {

@Override

publicvoid onClick(View v) {

Intent intent = new Intent();

intent.setAction(Intent.ACTION_DIAL);

intent.setData(Uri.parse("tel://10086"));

startActivity(intent);

}

});

 

ImageView imageView_popup_collection = (ImageView) popup_view

.findViewById(R.id.imageView_popup_collection);

imageView_popup_collection

.setOnClickListener(new OnClickListener() {

@Override

publicvoid onClick(View v) {

Intent intent = new Intent();

intent.setAction(Intent.ACTION_SENDTO);

intent.setData(Uri.parse("smsto:10086"));

intent.putExtra("sms_body", "该吃饭了,下课吧!");

startActivity(intent);

}

});

}

break;

case KeyEvent.KEYCODE_BACK:

if (popupWindow.isShowing()) {

popupWindow.dismiss();

returnfalse;

}

default:

break;

}

returnsuper.onKeyDown(keyCode, event);

}

 

@Override

publicboolean onCreateOptionsMenu(Menu menu) {

// Inflate the menu; this adds items to the action bar if it is present.

getMenuInflater().inflate(R.menu.main, menu);

returntrue;

}

 

@Override

publicboolean onMenuOpened(int featureId, Menu menu) {

returnfalse;

}

 

}

 

 

(二)、案例二:

 

1、效果图:


2、学习目的:

  • 再次学习PopupWindow的基本使用方法;
  • 学习资源中TypedArray的使用方法;
  • 掌握GridView的具体用法;
  • 学习PopupWindow的聚焦方法;
  • 学习View的OnKeyListener监听器的用法。

 

3、核心代码:

 

publicclass MainActivity extends Activity {

private TextView textView_info;

private List<String> list_title = null;

private List<Drawable> list_icons = null;

 

private PopupWindow popupWindow = null;

private View popup_view = null;

 

/*

* private int[] imgIds = new int[] { R.drawable.intercept_list,

* R.drawable.intercept_rule, R.drawable.intercepted_record,

* R.drawable.location, R.drawable.incoming_and_outgoing_setting,

* R.drawable.privacy_manager, R.drawable.ip, R.drawable.dial,

* R.drawable.useful };

* private String[] arrTitles = new String[] { "拦截名单", "拦截规则", "拦截记录",

* "归属地查询", "来去电设置", "隐私管理", "IP电话设置", "通讯记录", "常用号码" };

*/

 

@Override

protectedvoid onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

 

textView_info = (TextView) findViewById(R.id.text_main_info);

 

list_title = new ArrayList<String>();

TypedArray arrTitles = getResources().obtainTypedArray(R.array.titles);

for (int i = 0; i < arrTitles.length(); i++) {

list_title.add(arrTitles.getString(i));

}

 

list_icons = new ArrayList<Drawable>();

TypedArray arrIcons = getResources().obtainTypedArray(R.array.icons);

for (int i = 0; i < arrIcons.length(); i++) {

list_icons.add(arrIcons.getDrawable(i));

}

textView_info.setText(list_title.toString());

 

popup_view = getLayoutInflater().inflate(R.layout.popupwindow_menu,

null);

popup_view.setFocusableInTouchMode(true);

 

GridView popup_gridView = (GridView) popup_view

.findViewById(R.id.gridView_popup);

 

popup_gridView.setAdapter(new MyAdapter(list_title, list_icons));

popup_gridView.setOnItemClickListener(new OnItemClickListener() {

@Override

publicvoid onItemClick(AdapterView<?> arg0, View arg1,

int position, long id) {

textView_info.setText("您点击了:" + position);

}

});

 

textView_info.setOnClickListener(new OnClickListener() {

@Override

publicvoid onClick(View v) {

textView_info.setText("您点击了文字");

}

});

// 方法2的第二步:给popupWindow上的View增加键盘监听事件。目的是:能在再次点击menu按键的时候,让popupWindow消失。

popup_view.setOnKeyListener(new OnKeyListener() {

@Override

publicboolean onKey(View v, int keyCode, KeyEvent event) {

if (keyCode == KeyEvent.KEYCODE_MENU && popupWindow.isShowing()

&& event.getAction() == KeyEvent.ACTION_DOWN) {

popupWindow.dismiss();

}

returnfalse;

}

});

popupWindow = new PopupWindow(popup_view, LayoutParams.MATCH_PARENT,

LayoutParams.WRAP_CONTENT);

popupWindow.setBackgroundDrawable(new ColorDrawable(Color.WHITE));

}

 

@Override

publicboolean onKeyDown(int keyCode, KeyEvent event) {

switch (keyCode) {

case KeyEvent.KEYCODE_MENU:

if (!popupWindow.isShowing()) {

// 解决方法二:

// 方法2的第一步:让popupWindow聚焦。只有聚焦之后,其中的Gridview的每个item才能被监听到点击事件。

popupWindow.setFocusable(true);

popupWindow.showAtLocation(popup_view, Gravity.BOTTOM, 0, 0);

}

returntrue;

default:

break;

}

returnsuper.onKeyDown(keyCode, event);

}

 

class MyAdapter extends BaseAdapter {

private List<String> list_title = null;

private List<Drawable> list_icons = null;

 

public MyAdapter(List<String> list_title, List<Drawable> list_icons) {

this.list_title = list_title;

this.list_icons = list_icons;

}

 

@Override

publicint getCount() {

returnlist_title.size();

}

 

@Override

public Object getItem(int position) {

returnlist_title.get(position);

}

 

@Override

publiclong getItemId(int position) {

return position;

}

 

@Override

public View getView(int position, View convertView, ViewGroup parent) {

ViewHolder mHolder = null;

if (convertView == null) {

mHolder = new ViewHolder();

convertView = getLayoutInflater().inflate(

R.layout.item_gridview, parent, false);

mHolder.textView_item_gridview_title = (TextView) convertView

.findViewById(R.id.textView_item_gridview_title);

mHolder.imageView_item_gridview_icon = (ImageView) convertView

.findViewById(R.id.imageView_item_gridview_icon);

convertView.setTag(mHolder);

} else {

mHolder = (ViewHolder) convertView.getTag();

}

mHolder.textView_item_gridview_title.setText(list_title

.get(position));

mHolder.imageView_item_gridview_icon.setImageDrawable(list_icons

.get(position));

 

// 解决方法一:

// convertView.setOnClickListener(new OnClickListener() {

// @Override

// public void onClick(View v) {

// textView_info.setText(v.getTag().toString());

// }

// });

return convertView;

}

class ViewHolder {

private ImageView imageView_item_gridview_icon;

private TextView textView_item_gridview_title;

}

@Override

publicboolean onCreateOptionsMenu(Menu menu) {

getMenuInflater().inflate(R.menu.main, menu);

returnfalse;

}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值