Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> Android提高21篇之十八:自定義Menu(TabMenu)

Android提高21篇之十八:自定義Menu(TabMenu)

編輯:關於android開發

       用過UCWEB-Android版的人都應該對其特殊的menu有印象,把menu做成Tab-Menu(支持分頁的Menu),可以容納比Android傳統的menu更豐富的內容(Android的menu超過6項則縮略在[更多]裡),本文參考網上的例子(作者:CoffeeCole,email:[email protected]),對例子進行簡化以及封裝,使其作為一個復合控件融入自己的framework。

       先來看看本文程序運行的效果:

 Android提高21篇之十八:自定義Menu(TabMenu)

       TabMenu本身就是一個PopupWindow,PopupWindow上面放了兩個GridView,第一個GridView就是分頁標簽,位於PopupWindow的頂部,第二個GridView是菜單,位於PopupWindow的主體。為了實現PopupWindow的彈出/退出的動畫效果,本文使用了以下代碼:

       在工程的res文件夾裡添加anim子目錄,再新建文件popup_enter.xml:

XML/HTML代碼
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <set xmlns:android="http://schemas.android.com/apk/res/android">  
  3.         <translate android:fromYDelta="100%p" android:toYDelta="0" android:duration="1000" />  
  4.         <alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="1000" />  
  5. </set>   

       新建文件popup_exit.xml:

XML/HTML代碼
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <set xmlns:android="http://schemas.android.com/apk/res/android">  
  3.         <translate android:fromYDelta="0" android:toYDelta="100%p" android:duration="1000" />  
  4.         <alpha android:fromAlpha="1.0" android:toAlpha="0.0" android:duration="1000" />  
  5. </set>   

       在工程的values文件夾裡新建文件popup_animation.xml:

XML/HTML代碼
  1. <?xml version="1.0" encoding="utf-8"?>    
  2. <resources>       
  3.     <style name="PopupAnimation" parent="android:Animation">  
  4.         <item name="android:windowEnterAnimation">@anim/popup_enter</item>    
  5.         <item name="android:windowExitAnimation">@anim/popup_exit</item>     
  6.     </style>    
  7. </resources>   

       main.xml的源碼如下:

XML/HTML代碼
  1. <linearlayout android:id="@+id/LinearLayout01"   
  2.         android:layout_width="fill_parent" android:layout_height="fill_parent"  
  3.         xmlns:android="http://schemas.android.com/apk/res/android">  
  4.         <textview android:id="@+id/TextView01" android:layout_height="wrap_content"   
  5.                 android:layout_width="fill_parent" android:text="擴展Menu----hellogv">  

        TabMenu的封裝類TabMenu.java的源碼如下:

Java代碼
  1. package com.testTabMenu;  
  2. import android.content.Context;  
  3. import android.graphics.Color;  
  4. import android.graphics.drawable.ColorDrawable;  
  5. import android.view.Gravity;  
  6. import android.view.View;  
  7. import android.view.ViewGroup;  
  8. import android.widget.BaseAdapter;  
  9. import android.widget.GridView;  
  10. import android.widget.ImageView;  
  11. import android.widget.LinearLayout;  
  12. import android.widget.PopupWindow;  
  13. import android.widget.TextView;  
  14. import android.widget.AdapterView.OnItemClickListener;  
  15. import android.widget.LinearLayout.LayoutParams;  
  16. public class TabMenu extends PopupWindow{  
  17.         private GridView gvBody, gvTitle;  
  18.         private LinearLayout mLayout;  
  19.         private MenuTitleAdapter titleAdapter;  
  20.         public TabMenu(Context context,OnItemClickListener titleClick,OnItemClickListener bodyClick,  
  21.                         MenuTitleAdapter titleAdapter,int colorBgTabMenu,int aniTabMenu){  
  22.                 super(context);  
  23.                   
  24.                 mLayout = new LinearLayout(context);  
  25.                 mLayout.setOrientation(LinearLayout.VERTICAL);  
  26.                 //標題選項欄  
  27.                 gvTitle = new GridView(context);  
  28.                 gvTitle.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));  
  29.                 gvTitle.setNumColumns(titleAdapter.getCount());  
  30.                 gvTitle.setStretchMode(GridView.STRETCH_COLUMN_WIDTH);  
  31.                 gvTitle.setVerticalSpacing(1);  
  32.                 gvTitle.setHorizontalSpacing(1);  
  33.                 gvTitle.setGravity(Gravity.CENTER);  
  34.                 gvTitle.setOnItemClickListener(titleClick);  
  35.                 gvTitle.setAdapter(titleAdapter);  
  36.                 gvTitle.setSelector(new ColorDrawable(Color.TRANSPARENT));//選中的時候為透明色  
  37.                 this.titleAdapter=titleAdapter;  
  38.                 //子選項欄  
  39.                 gvBody = new GridView(context);  
  40.                 gvBody.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));  
  41.                 gvBody.setSelector(new ColorDrawable(Color.TRANSPARENT));//選中的時候為透明色  
  42.                 gvBody.setNumColumns(4);  
  43.                 gvBody.setStretchMode(GridView.STRETCH_COLUMN_WIDTH);  
  44.                 gvBody.setVerticalSpacing(10);  
  45.                 gvBody.setHorizontalSpacing(10);  
  46.                 gvBody.setPadding(10, 10, 10, 10);  
  47.                 gvBody.setGravity(Gravity.CENTER);  
  48.                 gvBody.setOnItemClickListener(bodyClick);  
  49.                 mLayout.addView(gvTitle);  
  50.                 mLayout.addView(gvBody);  
  51.                   
  52.                 //設置默認項  
  53.                 this.setContentView(mLayout);  
  54.                 this.setWidth(LayoutParams.FILL_PARENT);  
  55.                 this.setHeight(LayoutParams.WRAP_CONTENT);  
  56.                 this.setBackgroundDrawable(new ColorDrawable(colorBgTabMenu));// 設置TabMenu菜單背景  
  57.                 this.setAnimationStyle(aniTabMenu);  
  58.                 this.setFocusable(true);// menu菜單獲得焦點 如果沒有獲得焦點menu菜單中的控件事件無法響應  
  59.         }  
  60.           
  61.           
  62.         public void SetTitleSelect(int index)  
  63.         {  
  64.                 gvTitle.setSelection(index);  
  65.                 this.titleAdapter.SetFocus(index);  
  66.         }  
  67.           
  68.         public void SetBodySelect(int index,int colorSelBody)  
  69.         {  
  70.                 int count=gvBody.getChildCount();  
  71.                 for(int i=0;i<count;i++)  
  72.                 {  
  73.                         if(i!=index)  
  74.                                 ((LinearLayout)gvBody.getChildAt(i)).setBackgroundColor(Color.TRANSPARENT);  
  75.                 }  
  76.                 ((LinearLayout)gvBody.getChildAt(index)).setBackgroundColor(colorSelBody);  
  77.         }  
  78.           
  79.         public void SetBodyAdapter(MenuBodyAdapter bodyAdapter)  
  80.         {  
  81.                 gvBody.setAdapter(bodyAdapter);  
  82.         }  
  83.           
  84.         /** 
  85.          * 自定義Adapter,TabMenu的每個分頁的主體 
  86.          *  
  87.          */  
  88.         static public class MenuBodyAdapter extends BaseAdapter {  
  89.                 private Context mContext;  
  90.                 private int fontColor,fontSize;  
  91.                 private String[] texts;  
  92.                 private int[] resID;  
  93.                 /** 
  94.                  * 設置TabMenu的分頁主體 
  95.                  * @param context 調用方的上下文 
  96.                  * @param texts 按鈕集合的字符串數組 
  97.                  * @param resID 按鈕集合的圖標資源數組 
  98.                  * @param fontSize 按鈕字體大小 
  99.                  * @param color 按鈕字體顏色 
  100.                  */  
  101.                 public MenuBodyAdapter(Context context, String[] texts,int[] resID, int fontSize,int fontColor)   
  102.                 {  
  103.                         this.mContext = context;  
  104.                         this.fontColor = fontColor;  
  105.                         this.texts = texts;  
  106.                         this.fontSize=fontSize;  
  107.                         this.resID=resID;  
  108.                 }  
  109.                 public int getCount() {  
  110.                         return texts.length;  
  111.                 }  
  112.                 public Object getItem(int position) {  
  113.                           
  114.                         return makeMenyBody(position);  
  115.                 }  
  116.                 public long getItemId(int position) {  
  117.                         return position;  
  118.                 }  
  119.                   
  120.                 private LinearLayout makeMenyBody(int position)  
  121.                 {  
  122.                         LinearLayout result=new LinearLayout(this.mContext);  
  123.                         result.setOrientation(LinearLayout.VERTICAL);  
  124.                         result.setGravity(Gravity.CENTER_HORIZONTAL|Gravity.CENTER_VERTICAL);          
  125.                         result.setPadding(10, 10, 10, 10);  
  126.                           
  127.                         TextView text = new TextView(this.mContext);  
  128.                         text.setText(texts[position]);  
  129.                         text.setTextSize(fontSize);  
  130.                         text.setTextColor(fontColor);  
  131.                         text.setGravity(Gravity.CENTER);  
  132.                         text.setPadding(5, 5, 5, 5);  
  133.                         ImageView img=new ImageView(this.mContext);  
  134.                         img.setBackgroundResource(resID[position]);  
  135.                         result.addView(img,new LinearLayout.LayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT)));  
  136.                         result.addView(text);  
  137.                         return result;  
  138.                 }  
  139.                   
  140.                 public View getView(int position, View convertView, ViewGroup parent) {  
  141.                         return makeMenyBody(position);  
  142.                 }  
  143.         }  
  144.           
  145.           
  146.         /** 
  147.          * 自定義Adapter,TabMenu的分頁標簽部分 
  148.          *  
  149.          */  
  150.         static public class MenuTitleAdapter extends BaseAdapter {  
  151.                 private Context mContext;  
  152.         private int fontColor,unselcolor,selcolor;  
  153.         private TextView[] title;  
  154.         /** 
  155.          * 設置TabMenu的title 
  156.          * @param context 調用方的上下文 
  157.          * @param titles 分頁標簽的字符串數組 
  158.          * @param fontSize 字體大小 
  159.          * @param fontcolor 字體顏色 
  160.          * @param unselcolor 未選中項的背景色 
  161.          * @param selcolor 選中項的背景色 
  162.          */  
  163.         public MenuTitleAdapter(Context context, String[] titles, int fontSize,  
  164.                 int fontcolor,int unselcolor,int selcolor) {  
  165.             this.mContext = context;  
  166.             this.fontColor = fontcolor;  
  167.             this.unselcolor = unselcolor;  
  168.             this.selcolor=selcolor;  
  169.             this.title = new TextView[titles.length];  
  170.             for (int i = 0; i < titles.length; i++) {  
  171.                 title[i] = new TextView(mContext);  
  172.                 title[i].setText(titles[i]);  
  173.                 title[i].setTextSize(fontSize);  
  174.                 title[i].setTextColor(fontColor);  
  175.                 title[i].setGravity(Gravity.CENTER);  
  176.                 title[i].setPadding(10, 10, 10, 10);  
  177.             }  
  178.         }  
  179.         public int getCount() {  
  180.             return title.length;  
  181.         }  
  182.         public Object getItem(int position) {  
  183.             return title[position];  
  184.         }  
  185.         public long getItemId(int position) {  
  186.             return title[position].getId();  
  187.         }  
  188.         /** 
  189.          * 設置選中的效果 
  190.          */  
  191.         private void SetFocus(int index)  
  192.         {  
  193.                 for(int i=0;i<title.length;i++)  
  194.                 {  
  195.                         if(i!=index)  
  196.                         {  
  197.                                 title[i].setBackgroundDrawable(new ColorDrawable(unselcolor));//設置沒選中的顏色  
  198.                     title[i].setTextColor(fontColor);//設置沒選中項的字體顏色  
  199.                         }  
  200.                 }  
  201.                 title[index].setBackgroundColor(0x00);//設置選中項的顏色  
  202.             title[index].setTextColor(selcolor);//設置選中項的字體顏色  
  203.         }  
  204.           
  205.         public View getView(int position, View convertView, ViewGroup parent) {  
  206.             View v;  
  207.             if (convertView == null) {  
  208.                 v = title[position];  
  209.             } else {  
  210.                 v = convertView;  
  211.             }  
  212.             return v;  
  213.         }  
  214.         }  
  215. }  

       testTabMenu介紹了數據的定義以及TabMenu的使用,源碼如下:

Java代碼
  1. package com.testTabMenu;  
  2. import android.app.Activity;  
  3. import android.graphics.Color;  
  4. import android.os.Bundle;  
  5. import android.view.Gravity;  
  6. import android.view.Menu;  
  7. import android.view.View;  
  8. import android.widget.AdapterView;  
  9. import android.widget.AdapterView.OnItemClickListener;  
  10. import android.widget.Toast;  
  11. public class testTabMenu extends Activity {  
  12.         TabMenu.MenuBodyAdapter []bodyAdapter=new TabMenu.MenuBodyAdapter[3];  
  13.         TabMenu.MenuTitleAdapter titleAdapter;  
  14.         TabMenu tabMenu;  
  15.         int selTitle=0;  
  16.         @Override  
  17.         public void onCreate(Bundle savedInstanceState) {  
  18.                 super.onCreate(savedInstanceState);  
  19.                 setContentView(R.layout.main);  
  20.                 //設置分頁欄的標題  
  21.                 titleAdapter = new TabMenu.MenuTitleAdapter(this, new String[] { "常用",  
  22.                                 "設置", "工具" }, 16, 0xFF222222,Color.LTGRAY,Color.WHITE);  
  23.                 //定義每項分頁欄的內容  
  24.                 bodyAdapter[0]=new TabMenu.MenuBodyAdapter(this,new String[] { "常用1", "常用2", },   
  25.                                  new int[] { R.drawable.menu_test,  
  26.                                 R.drawable.menu_bookmark},13, 0xFFFFFFFF);  
  27.                    
  28.                 bodyAdapter[1]=new TabMenu.MenuBodyAdapter(this,new String[] { "設置1", "設置2",  
  29.                                         "設置3"}, new int[] { R.drawable.menu_edit,  
  30.                                         R.drawable.menu_delete, R.drawable.menu_fullscreen},13, 0xFFFFFFFF);  
  31.                    
  32.                 bodyAdapter[2]=new TabMenu.MenuBodyAdapter(this,new String[] { "工具1", "工具2",  
  33.                                         "工具3", "工具4" }, new int[] { R.drawable.menu_copy,  
  34.                                         R.drawable.menu_cut, R.drawable.menu_normalmode,  
  35.                                         R.drawable.menu_quit },13, 0xFFFFFFFF);  
  36.                    
  37.                    
  38.                 tabMenu=new TabMenu(this,  
  39.                                  new TitleClickEvent(),  
  40.                                  new BodyClickEvent(),  
  41.                                  titleAdapter,  
  42.                                  0x55123456,//TabMenu的背景顏色  
  43.                                  R.style.PopupAnimation);//出現與消失的動畫  
  44.                    
  45.                  tabMenu.update();  
  46.                  tabMenu.SetTitleSelect(0);  
  47.                  tabMenu.SetBodyAdapter(bodyAdapter[0]);  
  48.         }  
  49.           
  50.         class TitleClickEvent implements OnItemClickListener{  
  51.                 @Override  
  52.                 public void onItemClick(AdapterView arg0, View arg1, int arg2,  
  53.                                 long arg3) {  
  54.                         selTitle=arg2;  
  55.                         tabMenu.SetTitleSelect(arg2);  
  56.                         tabMenu.SetBodyAdapter(bodyAdapter[arg2]);  
  57.                 }  
  58.         }  
  59.           
  60.         class BodyClickEvent implements OnItemClickListener{  
  61.                 @Override  
  62.                 public void onItemClick(AdapterView arg0, View arg1, int arg2,  
  63.                                 long arg3) {  
  64.                         tabMenu.SetBodySelect(arg2,Color.GRAY);  
  65.                         String str="第"+String.valueOf(selTitle)+"欄/n/r"  
  66.                         +"第"+String.valueOf(arg2)+"項";  
  67.                         Toast.makeText(testTabMenu.this, str, 500).show();  
  68.                           
  69.                 }  
  70.                   
  71.         }  
  72.         @Override  
  73.         /** 
  74.          * 創建MENU 
  75.          */  
  76.         public boolean onCreateOptionsMenu(Menu menu) {  
  77.                 menu.add("menu");// 必須創建一項  
  78.                 return super.onCreateOptionsMenu(menu);  
  79.         }  
  80.         @Override  
  81.         /** 
  82.          * 攔截MENU 
  83.          */  
  84.         public boolean onMenuOpened(int featureId, Menu menu) {  
  85.                 if (tabMenu != null) {  
  86.                         if (tabMenu.isShowing())  
  87.                                 tabMenu.dismiss();  
  88.                         else {  
  89.                                 tabMenu.showAtLocation(findViewById(R.id.LinearLayout01),  
  90.                                                 Gravity.BOTTOM, 0, 0);  
  91.                         }  
  92.                 }  
  93.                 return false;// 返回為true 則顯示系統menu  
  94.         }  
  95.           
  96. }  
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved