EL : Compatible PopupMenu Class

EL : Compatible PopupMenu Class


    大约两周前, 在修复EL的 2.3.x的兼容问题时, 有一个是PopupMenu相关的, 这个类在API9才有的, 那么在2.3.x平台上就没法用了. 为了能够兼容, 当时用了PopupWindow.
    这两天考虑到PopupMenu后面还是很需要的, 且以前的封装仅仅是为了实现播放快速跳转的兼容功能, 没考虑再使用, 所以昨晚重新封装了下, 这样更加方便和实用了.

    实现的方式还是在2.3.x平台下使用PopupWindow来实现PopupMenu的功能, 但这次只需要在xml下定义个Menu资源就好了, 不再需要另行准备个PopupWindow所需的Layout资源了, 方便再次使用.
    4.x平台下直接就使用Menu资源初始PopupMenu了, 而使用PopupWindow时, 就需要先解析Menu资源文件, 得到所需的Item的ID和Title, 然后使用这些数据初始PopupWindow的View.



    
    封装的ELPopupMenu代码如下:
  1  package jie.android.el.view;
  2 
  3  import java.io.IOException;
  4  import java.util.ArrayList;
  5  import org.xmlpull.v1.XmlPullParserException;
  6 
  7  import jie.android.el.R;
  8  import jie.android.el.utils.Utils;
  9  import android.content.Context;
 10  import android.content.res.XmlResourceParser;
 11  import android.graphics.drawable.BitmapDrawable;
 12  import android.util.AttributeSet;
 13  import android.view.Gravity;
 14  import android.view.Menu;
 15  import android.view.MenuItem;
 16  import android.view.View;
 17  import android.view.View.OnClickListener;
 18  import android.view.ViewGroup.LayoutParams;
 19  import android.widget.Button;
 20  import android.widget.LinearLayout;
 21  import android.widget.PopupMenu;
 22  import android.widget.PopupMenu.OnMenuItemClickListener;
 23  import android.widget.PopupWindow;
 24 
 25  public  class ELPopupMenu {
 26 
 27      private  class MenuData {
 28          public  int id;
 29          public String title;
 30         
 31          public MenuData( int id, String title) {
 32              this.id = id;
 33              this.title = title;
 34         }
 35     }
 36     
 37      public  interface OnItemClickListener {
 38          public  void OnClick( int item);
 39     }
 40     
 41      private Context context;
 42      private  int resMenuId;
 43      private View parent;
 44      private Object popup;
 45      private OnItemClickListener listener;
 46     
 47      public ELPopupMenu(Context context,  int resMenuId, View parent, OnItemClickListener listener) {
 48          this.context = context;
 49          this.resMenuId = resMenuId;
 50          this.parent = parent;
 51          this.listener = listener;
 52         
 53         make();
 54     }
 55     
 56      private  void make() {
 57          if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
 58             popup = makePopupMenu(context, resMenuId, parent);
 59         }  else {
 60             popup = makePopupWindow(context, resMenuId, parent);
 61         }
 62     }
 63 
 64      private Object makePopupMenu(Context context,  int resId, View parent) {
 65         PopupMenu pm =  new PopupMenu(context, parent);
 66         pm.getMenuInflater().inflate(resId, pm.getMenu());
 67         pm.setOnMenuItemClickListener( new OnMenuItemClickListener() {
 68 
 69             @Override
 70              public  boolean onMenuItemClick(MenuItem menu) {
 71                  if (listener !=  null) {
 72                     listener.OnClick(menu.getItemId());
 73                      return  true;
 74                 } 
 75                  return  false;
 76             }            
 77         });
 78         
 79          return pm;
 80     }
 81 
 82      private  int getAttributeIntValue(Context context, String resId) {
 83          return Integer.valueOf(resId.substring(1));
 84     }
 85      private String getAttributeStringValue(Context context, String resId) {
 86          int id = Integer.valueOf(resId.substring(1));
 87          return context.getString(id);
 88     }
 89     
 90     
 91      private ArrayList<MenuData> analyseMenuResource(Context context,  int resId) {
 92         
 93         ArrayList<MenuData> menu =  new ArrayList<MenuData>();
 94         
 95         XmlResourceParser parser = context.getResources().getXml(resId);
 96         
 97          try {
 98              int event = parser.next();
 99              while (event != XmlResourceParser.END_DOCUMENT) {
100                  if (event == XmlResourceParser.START_TAG) {
101                      if (parser.getName().equals("item")) {
102                         menu.add( new MenuData(getAttributeIntValue(context, parser.getAttributeValue(Utils.NS_ANDROID, "id")),
103                                 getAttributeStringValue(context, parser.getAttributeValue(Utils.NS_ANDROID, "title"))));
104                     }
105                 }
106                 event = parser.next();
107             }
108             
109         }  catch (XmlPullParserException e) {
110              //  TODO Auto-generated catch block
111              e.printStackTrace();
112         }  catch (IOException e) {
113              //  TODO Auto-generated catch block
114              e.printStackTrace();
115         }
116         
117          return menu;
118     }
119     
120      private Object makePopupWindow(Context context,  int resId, View parent) {
121         
122         ArrayList<MenuData> menu = analyseMenuResource(context, resId);
123          if (menu.size() == 0) {
124              return  null;
125         }
126             
127         OnClickListener l =  new OnClickListener() {
128             @Override
129              public  void onClick(View v) {
130                  if (listener !=  null) {
131                     listener.OnClick(v.getId());
132                 }
133                  if (popup !=  null) {
134                     ((PopupWindow)popup).dismiss();
135                 }
136             }            
137         };        
138         
139         AttributeSet attrs = Utils.getAttributeSet(context, R.layout.layout_popmenu_window_template, "LinearLayout", R.id.linearLayout1);
140         LinearLayout ll =  new LinearLayout(context, attrs);
141         
142          int pos = 0;
143          for (MenuData data : menu) {
144              if (pos == 0) {
145                 attrs = Utils.getAttributeSet(context, R.layout.layout_popmenu_window_template, "Button", R.id.button1);
146             }  else  if (pos == menu.size() -1) {
147                 attrs = Utils.getAttributeSet(context, R.layout.layout_popmenu_window_template, "Button", R.id.button3);
148             }  else {
149                 attrs = Utils.getAttributeSet(context, R.layout.layout_popmenu_window_template, "Button", R.id.button2);
150             }
151             
152             Button btn =  new Button(context, attrs);
153             btn.setId(data.id);
154             btn.setText(data.title);
155             btn.setOnClickListener(l);
156             
157             ll.addView(btn, ll.generateLayoutParams(attrs));
158             
159             ++ pos;
160         }
161         
162         PopupWindow pw =  new PopupWindow(ll);
163          // pw.setWidth(250);
164          pw.setWidth(LayoutParams.WRAP_CONTENT);
165         pw.setHeight(LayoutParams.WRAP_CONTENT);
166         pw.setFocusable( true);
167         pw.setOutsideTouchable( true);
168         pw.setBackgroundDrawable( new BitmapDrawable());
169         
170          return pw;        
171     }
172     
173      public  void show() {
174         show(Gravity.LEFT | Gravity.BOTTOM, 16, 64);
175     }    
176 
177      public  void show( int gravity,  int x,  int y) {
178          if (popup !=  null) {
179              if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
180                 ((PopupMenu)popup).show();
181             }  else {
182                 ((PopupWindow)popup).showAtLocation(parent, gravity, x, y);
183             }
184         }
185     }    
186     
187      public  void setItemEnabled( int item,  boolean enabled) {
188          if (popup !=  null) {
189              if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
190                 Menu menu = ((PopupMenu)popup).getMenu();
191                 MenuItem sub = menu.findItem(item);
192                  if (sub !=  null) {
193                     sub.setEnabled(enabled);
194                 }
195             }  else {
196                 View p = ((PopupWindow)popup).getContentView();
197                 View v = p.findViewById(item);
198                 v.setEnabled(enabled);
199             }
200         }
201     }
202     
203 }
204 


    初始PopupWindow的View的资源模板文件如下:
 1  <? xml version="1.0" encoding="utf-8" ?>
 2  < LinearLayout  xmlns:android ="http://schemas.android.com/apk/res/android"
 3      android:id ="@+id/linearLayout1"
 4      android:layout_width ="match_parent"
 5      android:layout_height ="wrap_content"
 6      android:layout_marginLeft ="16dp"
 7      android:layout_marginRight ="16dp"
 8      android:background ="@android:color/darker_gray"
 9      android:orientation ="vertical"   >
10 
11      < Button
12           android:id ="@+id/button1"
13          android:layout_width ="match_parent"
14          android:layout_height ="wrap_content"
15          android:layout_marginTop ="4dp"   />
16 
17      < Button
18           android:id ="@+id/button2"
19          android:layout_width ="match_parent"
20          android:layout_height ="wrap_content"   />
21 
22      < Button
23           android:id ="@+id/button3"
24          android:layout_width ="match_parent"
25          android:layout_height ="wrap_content"
26          android:layout_marginBottom ="0dp"   />
27  </ LinearLayout >





你可能感兴趣的:(EL : Compatible PopupMenu Class)