歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Android PopupWindow模擬Windows開始菜單顯示消失效果

Android系統給我提供的菜單不盡人意,大多數情況下我們都是根據需求,重寫系統的菜單,達到想要的效果,下面就用PopupWindow兩種方式重寫系統菜單效果。

Android PopupWindow模擬Windows開始菜單顯示消失效果DEMO下載:

免費下載地址在 http://linux.linuxidc.com/

用戶名與密碼都是www.linuxidc.com

具體下載目錄在 /pub/Android源碼集錦/2011年/11月/Android PopupWindow模擬Windows開始菜單顯示消失效果/

  1. package com.jacp.app;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.Intent;  
  5. import android.os.Bundle;  
  6. import android.view.Gravity;  
  7. import android.view.KeyEvent;  
  8. import android.view.MotionEvent;  
  9. import android.view.View;  
  10. import android.view.View.OnClickListener;  
  11. import android.view.View.OnKeyListener;  
  12. import android.view.View.OnTouchListener;  
  13. import android.view.WindowManager;  
  14. import android.widget.AdapterView;  
  15. import android.widget.AdapterView.OnItemClickListener;  
  16. import android.widget.LinearLayout;  
  17. import android.widget.ListView;  
  18. import android.widget.PopupWindow;  
  19.   
  20. public class PopupWindowActivity extends Activity implements OnClickListener {  
  21.       
  22.     private PopupWindow mLeftMenu;  
  23.       
  24.     @Override  
  25.     public void onCreate(Bundle savedInstanceState) {  
  26.         super.onCreate(savedInstanceState);  
  27.         setContentView(R.layout.main);  
  28.   
  29.         // 注冊按鈕事件   
  30.         findViewById(R.id.left).setOnClickListener(this);  
  31.         findViewById(R.id.right).setOnClickListener(this);  
  32.     }  
  33.   
  34.     @Override  
  35.     public void onClick(View v) {  
  36.         switch (v.getId()) {  
  37.         case R.id.left:  
  38.             showLeftMenu();  
  39.             break;  
  40.         case R.id.right:  
  41.             startActivity(new Intent(this, PopupWindowSecondActivity.class));  
  42.             break;  
  43.         }  
  44.     }  
  45.       
  46.     /** 
  47.      * 顯示菜單 
  48.      * @return 如果菜單顯示則返回true,否則返回false 
  49.      */  
  50.     private boolean showLeftMenu() {  
  51.         if (hideLeftMenu())  
  52.         {  
  53.             return false;  
  54.         }  
  55.         LinearLayout leftLayout = (LinearLayout) getLayoutInflater().inflate(R.layout.menu_list, null);  
  56.         // 當菜單出現時,最外層布局接受Touch事件   
  57.         leftLayout.setOnTouchListener(new OnTouchListener()  
  58.         {  
  59.             @Override  
  60.             public boolean onTouch(View v, MotionEvent event)  
  61.             {  
  62.                 hideLeftMenu();  
  63.                 return false;  
  64.             }  
  65.         });  
  66.           
  67.         ListView list = (ListView) leftLayout.findViewById(R.id.item_list);  
  68.         String[] data = getResources().getStringArray(R.array.menu_item);  
  69.         int[] res = new int[data.length];  
  70.         for (int i = 0, length = data.length; i < length; i++)  
  71.         {  
  72.             res[i] = R.drawable.icon;  
  73.         }  
  74.         list.setAdapter(new PopupAdapter(this, data, res, R.layout.menu_item, R.id.item_image, R.id.item_text));  
  75.         list.setOnItemClickListener(new OnItemClickListener()  
  76.         {  
  77.             @Override  
  78.             public void onItemClick(AdapterView<?> parent, View view,  
  79.                     int position, long id)  
  80.             {  
  81.                 hideLeftMenu();  
  82.             }  
  83.         });  
  84.         // 當菜單出現時焦點會落在ListView上   
  85.         list.setOnKeyListener(new OnKeyListener()  
  86.         {  
  87.             @Override  
  88.             public boolean onKey(View v, int keyCode, KeyEvent event)  
  89.             {  
  90.                 // 此方法會調兩次,一次Down和一次Up   
  91.                 // 所以此處要攔截   
  92.                 if (event.getAction() == KeyEvent.ACTION_DOWN)  
  93.                 {  
  94.                     switch (keyCode)  
  95.                     {  
  96.                     case KeyEvent.KEYCODE_MENU:  
  97.                         return hideLeftMenu();  
  98.                     case KeyEvent.KEYCODE_BACK:  
  99.                         return hideLeftMenu();  
  100.                     }  
  101.                 }  
  102.                 return false;  
  103.             }  
  104.         });  
  105.           
  106.         // 設置菜單屬性   
  107.         mLeftMenu = new PopupWindow(leftLayout, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT);  
  108.         mLeftMenu.setWidth(150);  
  109.         // 設置菜單上是否可以聚焦   
  110.         mLeftMenu.setFocusable(true);  
  111.         // 當菜單出現時菜單以外的區域是否接受點擊事件   
  112.         mLeftMenu.setOutsideTouchable(true);  
  113.         // 設置菜單顯示的位置   
  114.         mLeftMenu.showAtLocation(leftLayout, Gravity.BOTTOM | Gravity.LEFT, 080);  
  115.         return true;  
  116.     }  
  117.       
  118.     /** 
  119.      * 隱藏菜單 
  120.      * @return 如果菜單隱藏則返回true,則否返回false 
  121.      */  
  122.     private boolean hideLeftMenu()  
  123.     {  
  124.         if (null != mLeftMenu && mLeftMenu.isShowing())  
  125.         {  
  126.             mLeftMenu.dismiss();  
  127.             mLeftMenu = null;  
  128.             return true;  
  129.         }  
  130.         return false;  
  131.     }  
  132.       
  133.     @Override  
  134.     public boolean onKeyDown(int keyCode, KeyEvent event)  
  135.     {  
  136.         switch (keyCode)   
  137.         {  
  138.         case KeyEvent.KEYCODE_BACK:  
  139.             hideLeftMenu();  
  140.             break;  
  141.         case KeyEvent.KEYCODE_MENU:  
  142.             showLeftMenu();  
  143.             break;  
  144.         }  
  145.         return super.onKeyDown(keyCode, event);  
  146.     }  
  147.       
  148. }  

其中有三點要注意:

1.PopupWindow的參數設置

  1. // 設置菜單上是否可以聚焦   
  2. mLeftMenu.setFocusable(true);  
  3. // 當菜單出現時菜單以外的區域是否接受點擊事件   
  4. mLeftMenu.setOutsideTouchable(true);  

2.當PopupWindow顯示時焦點會落在其中,所以監聽事件的是它裡面的View,如例中的Touch事件。按鍵事件是占整個View的ListView監聽的。很奇怪的是不是裡面的LinearLayout,如果高人知道,請在下面留言,小弟不甚感激。

3.最後一點是注意按鍵事件。例子中重寫了Activity的OnKeyDown事件,而在ListView中的OnKey方法必須攔截KeyDown事件。如果不攔截菜單出現就會消失,因為OnKey方法會因Down和Up調用兩次;如果攔截的是Up事件,情況也是一樣的,因為當菜單沒有出現按Menu鍵時,先執行Activity裡面的onKeyDown事件,菜單出現。注意菜單出現是Down事件,那Up呢?正好當PopupWindow出現時,ListView繼續執行事件,會執行OnKey事件,如果是攔截的Action是Up則會執行,所以整個事件會兩個地方執行。有人說在Activity裡面的OnKeyDown事件return true進行攔截不就行了,這樣事件就不會執行到PopupWindow上面,這樣想沒有錯,如果真的是那樣,那按Back鍵後,整個Activity就不會退出。

以上是第一種方法。

Copyright © Linux教程網 All Rights Reserved