当前位置: 代码迷 >> Android >> Android菜单的施用Menu
  详细解决方案

Android菜单的施用Menu

热度:33   发布时间:2016-04-28 08:16:50.0
Android菜单的使用Menu

Android使用菜单使用

    Android系统SDK对菜单提供了广泛的支持,这里我们介绍几种常用的菜单:常规菜单、子菜单、上下文菜单、图标菜单、辅助菜单和交替菜单。提供Android菜单支持的一个重要的类是Android.view.Menu,Android中每一个活动都与一个此类型的菜单对象相关联,包括众多的菜单项和子菜单。菜单项使用android.view.MenuItem表示,子菜单使用android.view.SubMenu表示。

   菜单项还具有名称(标题)、菜单项ID、排序和ID,可以使用排序ID来指定菜单项在菜单中的顺序,一些菜单排序数字范围保留给了某些类型的菜单。如:

   容器菜单项以0x10000开始并由常量Menu.CATEGORY_CONTAINER定义。

   系统菜单项以0x20000开始并由常量Menu.CATEGORY_SYSTEM定义。

   辅助菜单项以0x30000开始并由常量Menu.CATEGORY_SECONDAR定义

   交替菜单项以0x40000开始并由常量Menu.CATEGORY_ALTERNATIVE定义

 

1)常规菜单

 

1.1、创建菜单   

   常规菜单是指当我们按下Menu的时候弹出的菜单。Android SDK中无需从头开始创建菜单因为一个活动只与一个菜单关联,所以Android会为该活动创建此菜单,然后将它传递给Activity类的onCreateOptionsMenu回调。

	@Override	public boolean onCreateOptionsMenu(Menu menu) {		// TODO Auto-generated method stub		super.onCreateOptionsMenu(menu);		int groupId = 100;		int itemId = 1;		int orderId = 1;		menu.add(groupId, itemId, orderId, "item1");		menu.add(groupId, itemId+1, orderId+1, "item2");		return true;	}


   注意:在onCreateOptionsMenu中需要调用此方法的基类实现,以便系统能够使用系统菜单项填充菜单,为了使这项系统菜单项与其他类型菜单分开,Android从0x20000开始添加它们。添加菜单项的方法为 public MenuItem add(int groupId, int itemId, int order, CharSequence title)其中第一个参数表上组ID,第二个参数表示菜单项ID,在选择该菜单项时会将它发送给回调函数,第三个参数表示排序ID。这几个参数都是可选的,如果不希望指定任何ID,可以使用Menu.NONE。

最后一个参数是菜单项的名称或标题,除了是自由文本,也可以是R.java常量文件使用字符串资源。

   最后这个方法应该返回true,使菜单可见。如果返回false那么菜单项将不可见。

 

1.2、使用菜单组

   由于菜单项ID和排序ID与组ID是独立的,那么组有什么用呢?Android提供了一些基于组IDandroid.view.Menu类方法,可以使用这些方法操作组中的菜单项:

   public void removeGroup(int groupId)  删除给定组ID的所有菜单项

   public void setGroupCheckable(int group, boolean checkable, boolean exclusive)  设置在选中菜单项时在该菜单项中显示一个勾选标记。如果设置了exclusive标记那么只允许该组中的一个菜单项处于勾选状态。

   public void setGroupVisible(int group, boolean visible)  显示或隐藏给定组ID中所有item项

   public void setGroupEnabled(int group, boolean enable)   使能给定组ID中所有Item项

 

1.3、响应菜单项     

   Android中可以采用多种方式来响应菜单项单击。可以使用Activity类的onOptionsItemSelected方法,也可是使用单独的监听器,或者使用Intent。

1)通过onOptionsItemSelected响应菜单项

	@Override	public boolean onOptionsItemSelected(MenuItem item) {		// TODO Auto-generated method stub		if(item.getItemId() == 1) {			Toast.makeText(this, "Select Item 1", Toast.LENGTH_LONG).show();		} else if(item.getItemId() == 2) {			Toast.makeText(this, "Select Item 2", Toast.LENGTH_LONG).show();		}		return super.onContextItemSelected(item);	}

   这里通过MenuItem的getItemId()方法来检查菜单项的ID,然后执行相应操作。如果onOptionsItemSelected处理了一个菜单项,将返回true,此菜单项事件将不会再进一步传播,对于onOptionsItemSelected未处理的菜单项,应该通过调用基类的方法来处理,默认返回false。

2)通过监听器响应菜单项

  通过重写onOptionsItemSelected来响应菜单,是提供性能的推荐方法,菜单项还支持注册用作回调的监听器。首先需要实现onMenuItemClickListener接口,然后获取此实现的一个示例并传递给菜单项。当单机该菜单时调用onMenuItemClickListener接口的onMenuItemClick方法。

 

item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {						@Override			public boolean onMenuItemClick(MenuItem item) {				// TODO Auto-generated method stub				return false;			}		});


注意:如果onMenuItemClick返回true,将不会执行任何其他回调,监听器代码的优先级高于onOptionsItemSelected

 

3)使用Intent响应菜单项

   也可以使用MenuItem的setIntent(intent)方法,将菜单项与Intent关联。默认情况下菜单项没有与之关联的Intent,但是当Intent与菜单项关联后,并且没有其他方法处理菜单项时,默认将使用startActivity(intent)调用该intent。

 

2)图标菜单

   Android中不仅支持文本,还支持将图像或图标作为菜单内容。但是使用菜单项有些限制:不能将图标用于展开菜单,图标菜单不支持菜单勾选标记,如果图标菜单项中的文本太长,将从一定数量的字符之后截断。

   创建菜单项和创建基于文本的菜单项一样,然后使用MenuItem类的setIcon()方法来设置图像。

   MenuItem item = menu.add(base, base+1, base+1, "Item1");

   item.setIcon(R.drawable.img1);

 

3)子菜单

   Menu对象可以有多个SubMenu对象,每个SubMenu对象通过调用Menu.addSubMenu()方法被添加到Menu对象中。将菜单项添加到子菜单的方式与将菜单项添加到菜单的方式相同,因为SubMenu是派生自Menu。但是不能向子菜单添加更多的子菜单。

	private void addSubMenu(Menu menu) {		int base = Menu.FIRST + 1;		SubMenu subMenu = menu.addSubMenu(base, base+1, Menu.NONE, "subMenu");		subMenu.add(base, base+2, base+2, "sub item1");		subMenu.add(base, base+3, base+3, "sub item2");		subMenu.add(base, base+4, base+4, "sub item3");	}

 

4)上下文菜单

    Android中通过名为长单击的操作来支持上下文菜单,长单击的意思是在Android视图上按住的时间比平常稍微较长。上下文菜单被表示为ContextMenu类,像Menu一样,ContextMenu可以包含很多菜单项。活动只能拥有一个常规的视图菜单,但可以用于多个上下文菜单。尽管上下文菜单归视图拥有,但是填充上下文菜单的方法包含在activity类中,为activity.onCreateContextMenu()。

   注意:上下文菜单不支持快捷键、图标和子菜单。

4.1、为上下文菜单注册视图

  在活动的onCreate()方法中为上下文菜单注册视图,在活动中调用registerForContextMenu(View v);

Demo:

	protected void onCreate(Bundle savedInstanceState) {		super.onCreate(savedInstanceState);		setContentView(R.layout.activity_main);				button = (Button) this.findViewById(R.id.btn);		registerForContextMenu(button);	// 注册 长按弹出Menu列表	}

 

4.2、填充上下文菜单  

   为上下文菜单注册了视图之后,Android将使用此视图作为参数,调用onCreateContextMenu()方法,可以在该方法中为上下文填充菜单项。

   public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo)

   提供了三个参数,第一个参数是预先构造的ContextMenu对象,第二个参数是生成回调的视图(如上面的Button),第三个参数是ContextMenuInfo类,这个是视图向此方法传递附加信息的一种方式,视图需要完成此操作需要重写getContextMenuInfo()方法,并返回ContextMenuInfo的派生类。

	@Override	public void onCreateContextMenu(ContextMenu menu, View v,			ContextMenuInfo menuInfo) {		// TODO Auto-generated method stub		if(v.getId() == R.id.btn) {			menu.setHeaderTitle("这是一个ContextMenu");			menu.add(3, 200, 200, "Context Menu 1");			menu.add(3, 201, 201, "Context Menu 2");		}		super.onCreateContextMenu(menu, v, menuInfo);	}


4.3、响应上下文菜单    

    实现上下文菜单的最后一步是响应上下文菜单单击,响应上下文菜单的机制与响应选项菜单的机制类似,Android提供了一个onContextItemSelected方法。

	@Override	public boolean onContextItemSelected(MenuItem item) {		// TODO Auto-generated method stub		if(item.getItemId() == 200) {			Toast.makeText(this, "Select Item 1", Toast.LENGTH_LONG).show();		} else if(item.getItemId() == 201) {			Toast.makeText(this, "Select Item 2", Toast.LENGTH_LONG).show();		}		return super.onContextItemSelected(item);	}

 

5)交替菜单

    交替菜单支持Android上的多个应用程序相互使用,这些交替菜单是Android应用程序间通信或使用框架的一部分。交替菜单允许一个应用程序包含另一个应用程序的菜单,当选择交替菜单时,将使用该活动所需的数据URI启动目标应用程序或活动。调用的活动使用传入的Intent中的数据URI。

   要创建交替菜单项附加到菜单上,执行以下步骤,同时在onCreateOptionsMenu方法中设置该菜单

1、创建一个Intent,将它的数据URI设置为当前显示数据的URI。

2、将Intent的类别设置为CATEGORY_ALTERNATIVE

3、搜索允许对此URI类型支持的数据进行操作的活动。

4、将可以调用这些活动的Intent以菜单项的形式添加到菜单。

   通过this.getIntent().getData()获得可能在此活动上使用的数据的URI。然后找到使用此类数据的其他程序,我们使用一个Intent作为参数来进行搜索:

   Intent criteriIntent = new Intent(null, getIntent().getData());

   intent.addCategory(Intent.CATEGORY_ALTERNATIVE);

   现在我们可以告诉Menu对象搜索匹配活动,并将它们作为菜单选项进行添加:

   menu.addIntentOptions(

       Menu.CATEGORY_ALTERNATIVE, // Group

       Menu.CATEGORY_ALTERNATIVE, // Id

       Menu.CATEGORY_ALTERNATIVE, // Order

       this.getComponentName(),  // Name of the activity class displaying

       null,  // No specific

       criteriIntent, // intent

       0,

       null

   );

  匹配活动是指能够处理已为他提供的URI的活动,活动通常会使用URI、操作和类别在其描述文件中注册信息。Menu类的方法addIntentOptions负责查找与Intent的URI和类别特性匹配的活动,然后该方法使用合适的菜单项ID和排序ID,将这些活动添加到正确组下的菜单中。

 

使用菜单响应数据变化:

   到现在为止我们用的都是静态菜单,设置了菜单之后就不能根据屏幕内容改变菜单项。Android为我们提供了onPrepareOptionsMenu方法来创建动态菜单,此方法类似于onCreateOptionsMenu,但每次调用菜单时都会调用它。

 

   

  相关解决方案