zoukankan      html  css  js  c++  java
  • android自定义menu,PopUpWindow弹出菜单

    使用PopupWindow来做自定义menu,往PopupWindow增加一个子View,子View的布局就是menu的布局。

    出现和退出的动画:可以给PopUpWindow或它的子view添加。

    网上所有用PopupWindow做的menu有个共同特点:就是点击menu键出现PopupWindow,然后再点击menu键无法使PopupWindow退出/dismiss()。

    当给PopupWindow设置了setFocusable(true),menu显示后,点击menu其他任何地方,menu都会消失,但是这时候按钮的点击事件其实是不响应的。同时只响应键盘的返回键,其他按键均不响应,比如点击menu键,没有任何反应。

    要解决这个问题很简单,就是给PopupWindow的子View设置下面的代码:

    1. //sub_view 是PopupWindow的子View  
    2. sub_view.setFocusableInTouchMode(true);  
    3. sub_view.setOnKeyListener(new OnKeyListener() {  
    4.     @Override  
    5.     public boolean onKey(View v, int keyCode, KeyEvent event) {  
    6.         // TODO Auto-generated method stub  
    7.         if ((keyCode == KeyEvent.KEYCODE_MENU)&&(mPopupWindow.isShowing())) {  
    8.             mPopupWindow.dismiss();// 这里写明模拟menu的PopupWindow退出就行  
    9.             return true;  
    10.         }  
    11.         return false;  
    12.     }  
    13. });  


     记住,一定要给PopupWindow设置setFocusable(true),要不然点击menu其他地方以及返回键,menu都不会退出。且这时候是响应PopupWindow的parent的menu事件的。

    下面阐述为什么这么写之后,当PopupWindow显示后,点击menu键PopupWindow会退出的原因:

    首先得明白为什么给PopupWindow setFocusable(true)后,点击menu出现PopupWindow后再点击menu没反应的原因。

    PopupWindow初始化的时候一般都指定了在哪个View上出现,我们称这个View为parent。parent里面写了点击menu出现PopupWindow的事件,如果给PopupWindow setFocusable(true),此时屏幕的焦点在PopupWindow上面,肯定是不会响应parent的按键事件的,它只会响应PopupWindow的按键事件。

    但是PopupWindow的本质是Window,没有继承View类,自己没有onkeyDown或onkey或dispatchKey这些事件的。我刚开始试着实现这些接口,但是按键依然不响应,不知原因。因现在对按键的原理还不熟,无法阐述其原因。

    然后我想绕道而行,就是给PopupWindow的子View注册按键事件,setKeyListener,刚开始我在子View的xml设置了 android:focusable=”true” 但按键事件依然不响应。。。。纠结啊纠结。。。然后没得办法,我google了所有关于PopupWindow的文章。。。最后终于被我发现。。。需要给 PopupWindow的子View 设置setFocusableInTouchMode(true)。这时候按键事件就响应了。。。

    下面附上完整代码:

    1.    /*必须重写,否则点击MENU无反应  为了让他不显示,下面onMenuOpened()必须返回false*/  
    2. @Override  
    3. public boolean onCreateOptionsMenu(Menu menu) {  
    4.     menu.add("menu");// 必须创建一项  
    5.     return super.onCreateOptionsMenu(menu);  
    6. }  
    7. /** 
    8.  * 拦截MENU 
    9.  */  
    10. @Override  
    11. public boolean onMenuOpened(int featureId, Menu menu) {  
    12.     if(mPopupWindow != null){  
    13.         if(!mPopupWindow.isShowing()){  
    14.             /*最重要的一步:弹出显示   在指定的位置(parent)  最后两个参数 是相对于 x / y 轴的坐标*/  
    15.             mPopupWindow.showAtLocation(findViewById(R.id.linear_menu_parent), Gravity.BOTTOM, 00);  
    16.         }  
    17.     }  
    18.     return false;// 返回为true 则显示系统menu  
    19. }  
    20.   
    21.      
    22.    private void initPopuWindow(int menuViewID){  
    23.     LayoutInflater mLayoutInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);  
    24.     /*设置显示menu布局   view子VIEW*/  
    25.     sub_view = mLayoutInflater.inflate(menuViewID, null);  
    26.     /*第一个参数弹出显示view  后两个是窗口大小*/  
    27.     mPopupWindow = new PopupWindow(sub_view, LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);  
    28.     /*设置背景显示*/  
    29.     mPopupWindow.setBackgroundDrawable(getResources().getDrawable(R.drawable.bg_menu_popup));  
    30.     /*设置触摸外面时消失*/  
    31.     mPopupWindow.setOutsideTouchable(true);  
    32.     /*设置系统动画*/  
    33.     mPopupWindow.setAnimationStyle(android.R.style.Animation_Dialog);  
    34.     mPopupWindow.update();  
    35.     mPopupWindow.setTouchable(true);  
    36.     /*设置点击menu以外其他地方以及返回键退出*/  
    37.     mPopupWindow.setFocusable(true);  
    38.       
    39.     /** 1.解决再次点击MENU键无反应问题   
    40.      *  2.sub_view是PopupWindow的子View 
    41.      */  
    42.     sub_view.setFocusableInTouchMode(true);  
    43.     sub_view.setOnKeyListener(new OnKeyListener() {  
    44.         @Override  
    45.         public boolean onKey(View v, int keyCode, KeyEvent event) {  
    46.             // TODO Auto-generated method stub  
    47.             if ((keyCode == KeyEvent.KEYCODE_MENU)&&(mPopupWindow.isShowing())) {  
    48.                 mPopupWindow.dismiss();// 这里写明模拟menu的PopupWindow退出就行  
    49.                 return true;  
    50.             }  
    51.             return false;  
    52.         }  
    53.     });  
    54.       
    55.       
    56.     /*监听MENU事件*/  
    57.     menu = new View[3];  
    58.     menu[0] = sub_view.findViewById(R.id.menu_0);  
    59.     menu[1] = sub_view.findViewById(R.id.menu_1);  
    60.     menu[2] = sub_view.findViewById(R.id.menu_2);  
    61.       
    62.     menu[0].setOnClickListener(new OnClickListener() {  
    63.         @Override  
    64.         public void onClick(View v) {  
    65.             // doSomething  
    66.               
    67.         }  
    68.     });  
    69.       
    70.     menu[1].setOnClickListener(new OnClickListener() {  
    71.         @Override  
    72.         public void onClick(View v) {  
    73.             // doSomething  
    74.               
    75.         }  
    76.     });  
    77.       
    78.     menu[2].setOnClickListener(new OnClickListener() {  
    79.         @Override  
    80.         public void onClick(View v) {  
    81.             // doSomething  
    82.               
    83.         }  
    84.     });  
    85.    }  


     

    网上有模仿UCweb的自定义menu的源码,下面是三个比较经典的文章:

      1. Android提高十八篇之自定义Menu(TabMenu)
      2. 【源码发布】仿UCWEB7.4界面最新Menu菜单 源码放出~!
      3. 模仿UCweb菜单
      4. Android 菜单(OptionMenu)大全 建立你自己的菜单

         

         

      5. 转:http://blog.csdn.net/admin_/article/details/7278402
  • 相关阅读:
    sublime开启vim模式
    git命令行界面
    搬进Github
    【POJ 2886】Who Gets the Most Candies?
    【UVA 1451】Average
    【CodeForces 625A】Guest From the Past
    【ZOJ 3480】Duck Typing
    【POJ 3320】Jessica's Reading Problemc(尺取法)
    【HDU 1445】Ride to School
    【HDU 5578】Friendship of Frog
  • 原文地址:https://www.cnblogs.com/jiezzy/p/2640584.html
Copyright © 2011-2022 走看看