论坛首页 移动开发技术论坛

带图标 快捷键 Menu - 终极版

浏览 7294 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2010-05-04   最后修改:2010-05-05

Menu 改头换面 扩展如下:

 

1. 图标化文字

2. 快捷键功能 具体 参考xp - 菜单

 

 

[代码 步骤]

 

1. 定制化IconifiedTextItem 用于存放菜单选项需要的 图标资源 文字 快捷键

 

 

public class IconifiedTextItem {
	String text;
	Drawable icon;
	String shortcut;
	
public IconifiedTextItem(String s,Drawable d,String ss){
	text = s;
	icon = d;
	shortcut = ss;
}

public String getText(){
	return text;
}

public Drawable getIcon(){
	return icon;
}

public String getShortcut(){
	return shortcut;
}

}

 

 

2.  定义IconifiedTextAdapter 不仅用于存放具体菜单数据 即:图标 文字 快捷键 也定义菜单布局方式 故 extends BaseAdapter

 

public class IconifiedTextAdapter extends BaseAdapter {
	Context context;
	
	//存放菜单属性
	List<IconifiedTextItem> itemList;
	
	public IconifiedTextAdapter(Context c){
		context = c;
		
		itemList = new ArrayList<IconifiedTextItem>();
	}
	
	//添加一列菜单 包括:文字 图标 快捷键
	public void addItem(String string,int res,String shortcut){
		IconifiedTextItem it = new IconifiedTextItem(string,context.getResources().getDrawable(res),shortcut);
		itemList.add(it);
	}
	
	//根据快捷键名字  得出其索引值 返回-1 表示没有找到
	public int getShortcutByChar(char c){
		
		for(int i=0;i<itemList.size();i++){
			if(itemList.get(i).getShortcut().equals(""+c)){
				return i;
			}
		}
		return -1;
	}
	
	//----------------
	//extends BaseAdapter
	
	@Override
	public int getCount() {
		// TODO Auto-generated method stub
		return itemList.size();
	}

	@Override
	public Object getItem(int arg0) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public long getItemId(int arg0) {
		// TODO Auto-generated method stub
		return arg0;
	}

	@Override
	public View getView(int arg0, View arg1, ViewGroup arg2) {
		// TODO Auto-generated method stub
		LinearLayout lLayout = new LinearLayout(context);
		lLayout.setOrientation(LinearLayout.HORIZONTAL);
		
		ImageView image =new ImageView(context);
		image.setImageDrawable(itemList.get(arg0).getIcon());
		lLayout.addView(image, 
				new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,30));
		
		TextView text =new TextView(context);
		text.setText(itemList.get(arg0).getText());
		text.setGravity(Gravity.CENTER);
		lLayout.addView(text, 
				new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,30));
		
		TextView textShortcut =new TextView(context);
		textShortcut.setText(" ("+itemList.get(arg0).getShortcut()+")");
		textShortcut.setGravity(Gravity.CENTER);
		lLayout.addView(textShortcut, 
				new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,30));
		
		return lLayout;
	}

}

 

 

3. 定义函数setupMenu 用于执行菜单有关工作

 

public void setupMenu(){
    	viewMenu = this.getLayoutInflater().inflate(R.layout.menu, null);
    	popMenu = new PopupWindow(viewMenu,500,200);
    	lView = (ListView)viewMenu.findViewById(R.id.list);
    	
    	addExampleItem();
    	
    	addItemClickListener();
    	addItemShortcutListener();
    }

 

 

4. addExampleItem 用于添加菜单例子 并适配之  实现为:

 

public void addExampleItem(){
    	iTAdapter = new IconifiedTextAdapter(this);
    	iTAdapter.addItem("打开", R.drawable.favicon,"O");
    	iTAdapter.addItem("查看", R.drawable.favicon,"V");
    	iTAdapter.addItem("刷新", R.drawable.favicon,"E");
    	iTAdapter.addItem("新建", R.drawable.favicon,"w");
    	iTAdapter.addItem("属性", R.drawable.favicon,"R");
    	
    	lView.setAdapter(iTAdapter);
    }

 

 

5.  addItemClickListener 用于注册 菜单选项 可单击 然后执行之 实现为:

 

public void addItemClickListener(){
    	lView.setOnItemClickListener(new OnItemClickListener(){
			@Override
			public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
					long arg3) {
				// TODO Auto-generated method stub
				executeMenuItem(arg2);
				popMenu.dismiss();
			}
    		
    		
    	});
    }

 

 

6. addItemShortcutListener 用于注册 快捷键  接受用户按下快捷键  然后根据用户输入 查出其索引值 再执行之 实现为:

 

public void addItemShortcutListener(){
    	//使得 PopupWindow 处于 可输入 状态  默认是不接受的
    	popMenu.setFocusable(true);
    	popMenu.setInputMethodMode(PopupWindow.INPUT_METHOD_FROM_FOCUSABLE);
    	
    	lView.setOnKeyListener(new OnKeyListener(){

			@Override
			public boolean onKey(View arg0, int arg1, KeyEvent arg2) {
				// TODO Auto-generated method stub
				//解析 目标KeyEvent
				int code = arg2.getKeyCode();
				int action = arg2.getAction();
				
				//合法按键 且 按键抬起
				if((code >= KeyEvent.KEYCODE_A && code <= KeyEvent.KEYCODE_Z)&&
						action == KeyEvent.ACTION_UP){
					char key = (char)(arg2.getKeyCode() - KeyEvent.KEYCODE_A + 65);
					int id = iTAdapter.getShortcutByChar(key);
					
					if(id>=0){
						
						//to execute the dest operation
						executeMenuItem(id);
						
						popMenu.dismiss();
						return true;
					}
					return false;
				}
				else {//其他行为  按系统默认处理
					
					return false;
				}
			}
    		
    	});
    }

 

 

7.  注册onCreateOptionsMenu 当按下Menu 弹出PopupWindow

 

public boolean onCreateOptionsMenu(Menu menu) {
    	popMenu.showAtLocation(findViewById(R.id.main), Gravity.CENTER, 20, 20);
    	
    	//若返回值=false 表示 不弹出系统菜单  否则 弹出菜单
    	return false;
    }

 

 

8. 定义executeMenuItem 根据得到id 执行相关操作 因为此仅为演示 所以只会输出Log信息 大家可自行扩展

 

public void executeMenuItem(int id){
    	Log.d("TAG","Menu item:"+id);
    	
    }

 

 

9. emulator 运行效果 因为具体按键没有办法截图 所以只能看看界面

 

 

   发表时间:2010-05-05  
楼主能否把源代码公布一下?
0 请登录后投票
   发表时间:2010-05-05  
chinapengwei_wh 写道
楼主能否把源代码公布一下?

done~~
0 请登录后投票
   发表时间:2010-05-05  
那个“新建(W)”的快捷键是错误的哦。应该是大写的吧。
0 请登录后投票
   发表时间:2010-05-06  
drizzlemao 写道
那个“新建(W)”的快捷键是错误的哦。应该是大写的吧。

谢谢提醒 真仔细~~
0 请登录后投票
   发表时间:2010-05-18  
楼主好,你有没有什么方法可以在setFocusable之后,再点击menu或返回键,可以达到dismiss popupwindow的效果呢,我试了很多种方法都不ok
0 请登录后投票
   发表时间:2010-05-18  
sunersky 写道
楼主好,你有没有什么方法可以在setFocusable之后,再点击menu或返回键,可以达到dismiss popupwindow的效果呢,我试了很多种方法都不ok

默认就是如此啊 怎么你那边不是这样么?XD
0 请登录后投票
   发表时间:2010-05-20  
gryphone 写道
sunersky 写道
楼主好,你有没有什么方法可以在setFocusable之后,再点击menu或返回键,可以达到dismiss popupwindow的效果呢,我试了很多种方法都不ok

默认就是如此啊 怎么你那边不是这样么?XD

Hmm,再点击menu就不好用了呢。。苦恼Ing..如果!setFousable还可以关闭,set之后menu,就不可以了,返回还是ok.
0 请登录后投票
论坛首页 移动开发技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics