首页 > 代码库 > 用PopupWindow实现自定义overflow
用PopupWindow实现自定义overflow
当Action Barid的Action放不下时,系统会将其收集在overflow中。
用hierarchyviewer查看系统自己生成的Overflow,发现它本身就是popupWindow。
所以我们也可以用popUpWindow来写自己的overflow实现更多功能,做出像微信一样的效果。
第一次写,废话有点多,还望多包涵。
效果(GIF演示在文章底部):
最右边的Action(那个三点菜单)是自己添加的Action,使用了android开发包里的图标ic_action_overflow.png,可到官网下载。
首先在Item中添加Action,为了演示,添加了一个Submen
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" tools:context="com.example.popupwindowoverflow.MainActivity" ><item android:id="@+id/action_new" android:orderInCategory="1" android:title="SubMenu" android:icon="@drawable/ic_action_new" app:showAsAction="always"> <menu> <item android:id="@+id/submenu1" android:title="Accept" android:titleCondensed="Accept" android:icon="@drawable/ic_action_accept" /> <item android:id="@+id/submenu2" android:title="Cancel" android:titleCondensed="Cancel" android:icon="@drawable/ic_action_cancel" /> <item android:id="@+id/submenu3" android:title="Unread" android:titleCondensed="Unread" android:icon="@drawable/ic_action_unread" /> </menu></item><item android:id="@+id/action_overflow" android:orderInCategory="2" android:title="PopupWindow" android:icon="@drawable/ic_action_overflow" app:showAsAction="always"/></menu>
监听ID为action_overflow的Action,创建popupWindow弹出自己的overflow。
1 public boolean onOptionsItemSelected(MenuItem item) { 2 // Handle action bar item clicks here. The action bar will 3 // automatically handle clicks on the Home/Up button, so long 4 // as you specify a parent activity in AndroidManifest.xml. 5 int id = item.getItemId(); 6 switch (id) { 7 case R.id.action_overflow: 8 popUpMyOverflow();//弹出自定义overflow 9 return true;10 }11 return super.onOptionsItemSelected(item);12 }
下面介绍popUpMyOverflow()方法,就是通过它弹出了我们的overflow,自定义overflow的布局文件就是R.layout.action_overflow_popwindow,这里就不贴出来啦。
1 public void popUpMyOverflow() { 2 /** 3 * 定位PopupWindow,让它恰好显示在Action Bar的下方。 通过设置Gravity,确定PopupWindow的大致位置。 4 * 首先获得状态栏的高度,再获取Action bar的高度,这两者相加设置y方向的offset样PopupWindow就显示在action 5 * bar的下方了。 通过dp计算出px,就可以在不同密度屏幕统一X方向的offset.但是要注意不要让背景阴影大于所设置的offset, 6 * 否则阴影的宽度为offset. 7 */ 8 // 获取状态栏高度 9 Rect frame = new Rect();10 getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);11 // 状态栏高度:frame.top12 int xOffset = frame.top+getActionBar().getHeight()-25;//减去阴影宽度,适配UI.13 int yOffset = Dp2Px(this, 5f); //设置x方向offset为5dp14 View parentView = getLayoutInflater().inflate(R.layout.activity_main,15 null);16 View popView = getLayoutInflater().inflate(17 R.layout.action_overflow_popwindow, null);18 PopupWindow popWind = new PopupWindow(popView,19 LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, true);//popView即popupWindow的布局,ture设置focusAble.20 21 //必须设置BackgroundDrawable后setOutsideTouchable(true)才会有效。这里在XML中定义背景,所以这里设置为null;22 popWind.setBackgroundDrawable(new BitmapDrawable(getResources(),23 (Bitmap) null));24 popWind.setOutsideTouchable(true); //点击外部关闭。25 popWind.setAnimationStyle(android.R.style.Animation_Dialog); //设置一个动画。26 //设置Gravity,让它显示在右上角。27 popWind.showAtLocation(parentView, Gravity.RIGHT | Gravity.TOP,28 yOffset, xOffset);29 }
在android中,为了适配不同屏幕密度和尺寸,android用了Dp单位,但是在Java代码中多是接受px单位的尺寸,所以这里要转换一下。
Dp转换Px的方法。
1 public int Dp2Px(Context context, float dp) {2 final float scale = context.getResources().getDisplayMetrics().density;3 return (int) (dp * scale + 0.5f);4 }
好的,现在我们有了所有要显示自定义Overflow的东西了!运行你的app吧。
最终效果:
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。