欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android 使用PopupWindow实现弹出更多的菜单实例详解

程序员文章站 2022-08-02 15:18:55
最近想要做一个弹出更多的菜单,而原生的弹出菜单却不是我们想要的效果,所以必然要自定义菜单咯。本人也是借鉴网上的资料进行封装的,感觉还蛮不错的。 原生的菜单如下图:...

最近想要做一个弹出更多的菜单,而原生的弹出菜单却不是我们想要的效果,所以必然要自定义菜单咯。本人也是借鉴网上的资料进行封装的,感觉还蛮不错的。

原生的菜单如下图:

Android 使用PopupWindow实现弹出更多的菜单实例详解

自定义之后的效果图:

Android 使用PopupWindow实现弹出更多的菜单实例详解Android 使用PopupWindow实现弹出更多的菜单实例详解Android 使用PopupWindow实现弹出更多的菜单实例详解

是不是看到这里之后,对比可知,原生的效果不太理想,所以还是再自己定义吧!

1、popupwindow可以说是一个浮动在activity之上的容器,通常用来显示自定义的视图。弹出菜单的封装popmenumore

/** 
 * 对弹出菜单的封装. 
 * http://blog.csdn.net/maosidiaoxian/article/details/39178167 
 * author: msdx (645079761@qq.com) 
 * time: 14-6-13 下午1:51 
 */ 
public class popmenumore { 
 /** 
 * 上下文. 
 */ 
 private context mcontext; 
 /** 
 * 菜单项 
 */ 
 private arraylist<popmenumoreitem> mitemlist; 
 /** 
 * 列表适配器. 
 */ 
 private baseadapter madapter; 
 /** 
 * 菜单选择监听. 
 */ 
 private onitemselectedlistener mlistener; 
 /** 
 * 下角图标 
 */ 
 private imageview cornericon; 
 /** 
 * 列表. 
 */ 
 private listview mlistview; 
 /** 
 * 弹出窗口. 
 */ 
 private popupwindow mpopupwindow; 
 public popmenumore(context context) { 
 mcontext = context; 
 mitemlist = new arraylist<>(); 
 view view = oncreateview(context); 
 view.setfocusableintouchmode(true); 
 madapter = oncreateadapter(context, mitemlist); 
 cornericon = findcornerview(view); 
 mlistview = findlistview(view); 
 mlistview.setadapter(madapter); 
 mlistview.setonitemclicklistener(new adapterview.onitemclicklistener() { 
  @override 
  public void onitemclick(adapterview<?> parent, view view, int position, long id) { 
  popmenumoreitem item = (popmenumoreitem) madapter.getitem(position); 
  if (mlistener != null) { 
   mlistener.selected(view, item, position); 
  } 
  mpopupwindow.dismiss(); 
  } 
 }); 
 view.setonkeylistener(new view.onkeylistener() { 
  @override 
  public boolean onkey(view v, int keycode, keyevent event) { 
  if (keycode == keyevent.keycode_menu && mpopupwindow.isshowing()) { 
   mpopupwindow.dismiss(); 
   return true; 
  } 
  return false; 
  } 
 }); 
 mpopupwindow = new popupwindow(view, viewgroup.layoutparams.wrap_content, viewgroup.layoutparams.wrap_content, true); 
 mpopupwindow.setbackgrounddrawable(new colordrawable(0x00000000)); 
 setbackgroundcolor(color.parsecolor("#000000")); 
 setcorner(r.mipmap.triangle); 
 } 
 /** 
 * 设置listview背景 
 * 
 * @param argb color.parsecolor("..") 
 */ 
 public void setbackgroundcolor(int argb) { 
// int strokewidth = 5; // 3dp 边框宽度 
 int roundradius = 5; // 8dp 圆角半径 
// int strokecolor = color.parsecolor("#2e3135");//边框颜色 
// int fillcolor = color.parsecolor("#dfdfe0");//内部填充颜色 
 gradientdrawable gd = new gradientdrawable();//创建drawable 
 gd.setcolor(argb); 
 gd.setcornerradius(roundradius); 
// gd.setstroke(strokewidth, strokecolor); 
 mlistview.setbackgrounddrawable(gd); 
 } 
 /** 
 * 设置下角图标 
 * 
 * @param resid 
 */ 
 public void setcorner(int resid) { 
 cornericon.setbackgroundresource(resid); 
 } 
 protected view oncreateview(context context) { 
 return layoutinflater.from(context).inflate(r.layout.layout_popmenu_more, null); 
 } 
 protected imageview findcornerview(view view) { 
 return (imageview) view.findviewbyid(r.id.corner_iv); 
 } 
 protected listview findlistview(view view) { 
 return (listview) view.findviewbyid(r.id.menu_listview); 
 } 
 /** 
 * 菜单列表中的适配器. 
 * 
 * @param context 
 * @param items 表示所有菜单项. 
 * @return 
 */ 
 protected baseadapter oncreateadapter(context context, arraylist<popmenumoreitem> items) { 
 return new popmenumoreadapter(context, items); 
 } 
 /** 
 * 添加菜单项 
 * 
 * @param item 
 */ 
 public void additem(popmenumoreitem item) { 
 mitemlist.add(item); 
 madapter.notifydatasetchanged(); 
 } 
 public void additems(list<popmenumoreitem> items) { 
 if (items != null) { 
  mitemlist.clear(); 
 } 
 for (popmenumoreitem item : items) { 
  mitemlist.add(item); 
 } 
 madapter.notifydatasetchanged(); 
 } 
 
 /** 
 * 作为指定view的下拉控制显示. 
 * 
 * @param parent 所指定的view 
 */ 
 public void showasdropdown(view parent) { 
 mpopupwindow.showasdropdown(parent); 
 } 
 /** 
 * 隐藏菜单. 
 */ 
 public void dismiss() { 
 mpopupwindow.dismiss(); 
 } 
 /** 
 * 设置菜单选择监听. 
 * 
 * @param listener 监听器. 
 */ 
 public void setonitemselectedlistener(onitemselectedlistener listener) { 
 mlistener = listener; 
 } 
 /** 
 * 当前菜单是否正在显示. 
 * 
 * @return 
 */ 
 public boolean isshowing() { 
 return mpopupwindow.isshowing(); 
 } 
 /** 
 * 菜单项选择监听接口. 
 */ 
 public interface onitemselectedlistener { 
 /** 
  * 菜单被选择时的回调接口. 
  * 
  * @param view 被选择的内容的view. 
  * @param item 被选择的菜单项. 
  * @param position 被选择的位置. 
  */ 
 void selected(view view, popmenumoreitem item, int position); 
 } 
} 

2、菜单中listview的适配器:popmenumoreadapter

/** 
 * @author soban 
 * @create 2017/4/12 10:29. 
 */ 
public class popmenumoreadapter extends baseadapter { 
 private arraylist<popmenumoreitem> items; 
 private context context; 
 public popmenumoreadapter(context context, arraylist<popmenumoreitem> items) { 
 this.context = context; 
 this.items = items; 
 } 
 @override 
 public int getcount() { 
 return items.size(); 
 } 
 @override 
 public popmenumoreitem getitem(int position) { 
 return items.get(position); 
 } 
 @override 
 public long getitemid(int position) { 
 return position; 
 } 
 @override 
 public view getview(int position, view view, viewgroup parent) { 
 if (view == null) { 
  view = layoutinflater.from(context).inflate(r.layout.item_popmenu_more, null); 
  viewholder holder = new viewholder(); 
  holder.icon = (imageview) view.findviewbyid(r.id.menu_icon); 
  holder.text = (textview) view.findviewbyid(r.id.menu_text); 
  view.settag(holder); 
 } else if (view.getparent() != null) { 
  ((viewgroup) view.getparent()).removeview(view); 
 } 
 viewholder holder = (viewholder) view.gettag(); 
 popmenumoreitem item = items.get(position); 
 if (item.getresid() == 0) { 
  holder.icon.setvisibility(view.gone); 
 } 
 holder.text.settext(item.gettext()); 
 return view; 
 } 
 private class viewholder { 
 imageview icon; 
 textview text; 
 } 
} 

3、菜单项中item:  popmenumoreitem

/** 
 * 菜单项. 
 */ 
public class popmenumoreitem { 
 public int id; //标识 
 public int resid; //资源图标 
 public string text;//文字 
 public popmenumoreitem(int id, string text) { 
 this.id = id; 
 this.resid = 0; 
 this.text = text; 
 } 
 public popmenumoreitem(int id, int resid, string text) { 
 this.id = id; 
 this.resid = resid; 
 this.text = text; 
 } 
 public int getid() { 
 return id; 
 } 
 public void setid(int id) { 
 this.id = id; 
 } 
 public int getresid() { 
 return resid; 
 } 
 public void setresid(int resid) { 
 this.resid = resid; 
 } 
 public string gettext() { 
 return text; 
 } 
 public void settext(string text) { 
 this.text = text; 
 } 
} 

4、宽度适配内容、不滚动的listview:popmenumorelistview

/** 
 * 宽度适配内容的listview. 
 * author: msdx (645079761@qq.com) 
 * time: 14-9-2 下午5:14 
 */ 
public class popmenumorelistview extends listview { 
 public popmenumorelistview(context context) { 
 super(context); 
 } 
 public popmenumorelistview(context context, attributeset attrs) { 
 super(context, attrs); 
 } 
 public popmenumorelistview(context context, attributeset attrs, int defstyle) { 
 super(context, attrs, defstyle); 
 } 
 @override 
 protected void onmeasure(int widthmeasurespec, int heightmeasurespec) { 
 int width = 0; 
 for (int i = 0; i < getchildcount(); i++) { 
  view child = getchildat(i); 
  child.measure(measurespec.makemeasurespec(0, measurespec.unspecified), heightmeasurespec); 
  int w = child.getmeasuredwidth(); 
  if (w > width) width = w; 
 } 
 widthmeasurespec = measurespec.makemeasurespec(width + getpaddingleft() + getpaddingright(), measurespec.exactly); 
 super.onmeasure(widthmeasurespec, heightmeasurespec); 
 } 
} 

5、item的布局:item_popmenu_more.xml

<?xml version="1.0" encoding="utf-8"?> 
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android" 
 android:layout_width="wrap_content" 
 android:layout_height="wrap_content" 
 android:paddingbottom="10dip" 
 android:paddingleft="20dip" 
 android:paddingright="20dip" 
 android:paddingtop="10dip"> 
 <imageview 
 android:id="@+id/menu_icon" 
 android:layout_width="wrap_content" 
 android:layout_height="wrap_content" 
 android:layout_gravity="center_vertical" 
 android:layout_marginleft="5dip" 
 android:layout_marginright="5dip" 
 android:src="@mipmap/demand_icon_location" /> 
 <textview 
 android:id="@+id/menu_text" 
 android:layout_width="wrap_content" 
 android:layout_height="wrap_content" 
 android:layout_gravity="center_vertical" 
 android:singleline="true" 
 android:textcolor="#ffffff" /> 
</linearlayout> 

6、更多菜单的布局:layout_popmenu_more.xml

<?xml version="1.0" encoding="utf-8"?> 
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android" 
 android:layout_width="match_parent" 
 android:layout_height="wrap_content" 
 android:orientation="vertical" 
 android:paddingright="5dip"> 
 <imageview 
 android:id="@+id/corner_iv" 
 android:layout_width="wrap_content" 
 android:layout_height="wrap_content" 
 android:layout_gravity="right" 
 android:layout_marginright="15dip" 
 android:contentdescription="@null" /> 
 <soban.orderscroll.popmenumorelistview 
 android:id="@+id/menu_listview" 
 android:layout_width="wrap_content" 
 android:layout_height="wrap_content" 
 android:layout_gravity="right" 
 android:cachecolorhint="@android:color/transparent" 
 android:listselector="@android:color/transparent" 
 android:divider="#ffffff" 
 android:dividerheight="1px" 
 android:focusable="true" /> 
</linearlayout> 

7、例子activity: mainactivity

public class mainactivity extends activity { 
 private static final int user_search = 0; 
 private static final int user_add = 1; 
 private popmenumore mmenu; 
 private textview mtextview; 
 @override 
 protected void oncreate(bundle savedinstancestate) { 
 super.oncreate(savedinstancestate); 
 setcontentview(r.layout.activity_main); 
 initmenu(); 
 mtextview = (textview) findviewbyid(r.id.hello_tv); 
 mtextview.setonclicklistener(new view.onclicklistener() { 
  @override 
  public void onclick(view view) { 
  mmenu.showasdropdown(mtextview); 
  } 
 }); 
 } 
 private void initmenu() { 
 mmenu = new popmenumore(this); 
 // mmenu.setcorner(r.mipmap.demand_icon_location); 
 // mmenu.setbackgroundcolor(color.parsecolor("#ff8800")); 
 arraylist<popmenumoreitem> items = new arraylist<>(); 
 items.add(new popmenumoreitem(user_search, "搜索")); 
 items.add(new popmenumoreitem(user_add, "添加")); 
 items.add(new popmenumoreitem(user_search, "搜索")); 
 items.add(new popmenumoreitem(user_add, "添加")); 
 items.add(new popmenumoreitem(user_search, "搜索")); 
 items.add(new popmenumoreitem(user_add, "添加")); 
 /*items.add(new popmenumoreitem(user_search, r.mipmap.demand_icon_number, "搜索")); 
 items.add(new popmenumoreitem(user_add, r.mipmap.demand_icon_location, "添加")); 
 items.add(new popmenumoreitem(user_search, r.mipmap.demand_icon_number, "搜索")); 
 items.add(new popmenumoreitem(user_add, r.mipmap.demand_icon_location, "添加")); 
 items.add(new popmenumoreitem(user_search, r.mipmap.demand_icon_number, "搜索")); 
 items.add(new popmenumoreitem(user_add, r.mipmap.demand_icon_location, "添加"));*/ 
 mmenu.additems(items); 
 mmenu.setonitemselectedlistener(new popmenumore.onitemselectedlistener() { 
  @override 
  public void selected(view view, popmenumoreitem item, int position) { 
  switch (item.id) { 
   case user_search: 
//   startactivity(new intent(this, usersearchactivity.class)); 
   break; 
   case user_add: 
//   startactivity(new intent(getactivity(), useraddactivity.class)); 
   break; 
  } 
  } 
 }); 
 } 
} 

8、例子布局:activity_main.xml

<?xml version="1.0" encoding="utf-8"?> 
<relativelayout xmlns:android="http://schemas.android.com/apk/res/android" 
 xmlns:tools="http://schemas.android.com/tools" 
 android:id="@+id/activity_main" 
 android:layout_width="match_parent" 
 android:layout_height="match_parent" 
 android:paddingbottom="@dimen/activity_vertical_margin" 
 android:paddingleft="@dimen/activity_horizontal_margin" 
 android:paddingright="@dimen/activity_horizontal_margin" 
 android:paddingtop="@dimen/activity_vertical_margin"> 
 <textview 
 android:id="@+id/hello_tv" 
 android:layout_width="wrap_content" 
 android:layout_height="wrap_content" 
 android:text="hello world!" /> 
</relativelayout>

9、所需资源文件:

Android 使用PopupWindow实现弹出更多的菜单实例详解Android 使用PopupWindow实现弹出更多的菜单实例详解Android 使用PopupWindow实现弹出更多的菜单实例详解

参考:

android使用popupwindow实现页面点击顶部弹出下拉菜单

以上所述是小编给大家介绍的android 使用popupwindow实现弹出更多的菜单实例详解,希望对大家有所帮助