Android用PopupWindow实现自定义overflow

作者:李金尧 时间:2021-08-08 22:56:06 

本文实例为大家分享了PopupWindow实现自定义overflow的具体代码,供大家参考,具体内容如下

当Action Bar的Action放不下时,系统会将其收集在overflow中。

用hierarchyviewer查看系统自己生成的Overflow,发现它本身就是popupWindow。

所以我们也可以用popUpWindow来写自己的overflow实现更多功能,做出像微信一样的效果。

第一次写,废话有点多,还望多包涵。

效果(GIF演示在文章底部):

Android用PopupWindow实现自定义overflow

最右边的Action(那个三点菜单)是自己添加的Action,使用了android开发包里的图标ic_action_overflow.png,可到官网下载。

首先在Item中添加Action,为了演示,添加了一个Submenu


<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。


public boolean onOptionsItemSelected(MenuItem item) {
   // Handle action bar item clicks here. The action bar will
   // automatically handle clicks on the Home/Up button, so long
   // as you specify a parent activity in AndroidManifest.xml.    
   int id = item.getItemId();
   switch (id) {
   case R.id.action_overflow:
     popUpMyOverflow();//弹出自定义overflow
     return true;
   }
   return super.onOptionsItemSelected(item);
 }

 下面介绍popUpMyOverflow()方法,就是通过它弹出了我们的overflow,自定义overflow的布局文件就是R.layout.action_overflow_popwindow,这里就不贴出来啦。


public void popUpMyOverflow() {
   /**
    * 定位PopupWindow,让它恰好显示在Action Bar的下方。 通过设置Gravity,确定PopupWindow的大致位置。
    * 首先获得状态栏的高度,再获取Action bar的高度,这两者相加设置y方向的offset样PopupWindow就显示在action
    * bar的下方了。 通过dp计算出px,就可以在不同密度屏幕统一X方向的offset.但是要注意不要让背景阴影大于所设置的offset,
    * 否则阴影的宽度为offset.
    */
   // 获取状态栏高度
   Rect frame = new Rect();
   getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
//    状态栏高度:frame.top
   int xOffset = frame.top+getActionBar().getHeight()-25;//减去阴影宽度,适配UI.
   int yOffset = Dp2Px(this, 5f); //设置x方向offset为5dp
   View parentView = getLayoutInflater().inflate(R.layout.activity_main,
       null);
   View popView = getLayoutInflater().inflate(
       R.layout.action_overflow_popwindow, null);
   PopupWindow popWind = new PopupWindow(popView,
       LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, true);//popView即popupWindow的布局,ture设置focusAble.

//必须设置BackgroundDrawable后setOutsideTouchable(true)才会有效。这里在XML中定义背景,所以这里设置为null;
   popWind.setBackgroundDrawable(new BitmapDrawable(getResources(),
       (Bitmap) null));
   popWind.setOutsideTouchable(true); //点击外部关闭。
   popWind.setAnimationStyle(android.R.style.Animation_Dialog);  //设置一个动画。
   //设置Gravity,让它显示在右上角。
   popWind.showAtLocation(parentView, Gravity.RIGHT | Gravity.TOP,
       yOffset, xOffset);
 }

在android中,为了适配不同屏幕密度和尺寸,android用了Dp单位,但是在Java代码中多是接受px单位的尺寸,所以这里要转换一下。

Dp转换Px的方法。


public int Dp2Px(Context context, float dp) {
  final float scale = context.getResources().getDisplayMetrics().density;
   return (int) (dp * scale + 0.5f);
 }

好的,现在我们有了所有要显示自定义Overflow的东西了!运行你的app吧。

最终效果:

Android用PopupWindow实现自定义overflow

标签:Android,PopupWindow,overflow
0
投稿

猜你喜欢

  • C# 正则表达式常用的符号和模式解析(最新推荐)

    2021-07-05 16:01:22
  • Android view绘制流程详解

    2023-05-16 07:53:25
  • mybatis日志打印的两款IDEA插件推荐

    2022-01-12 07:55:52
  • 详解Java线程同步器CountDownLatch

    2023-08-23 18:42:39
  • Unity Shader实现黑幕过场效果

    2022-01-13 00:18:10
  • C#备忘录人生存档的设计模式实例

    2022-06-15 12:40:38
  • SpringBoot之Json的序列化和反序列化问题

    2021-11-12 07:17:29
  • C# WinForm制作异形窗体与控件的方法

    2023-11-07 11:09:28
  • 浅谈java异常链与异常丢失

    2023-10-24 21:53:38
  • 详解Android Activity中的几种监听器和实现方式

    2022-11-02 11:26:05
  • springboot vue组件开发实现接口断言功能

    2023-11-12 10:26:53
  • 深入讲解SPI 在 Spring 中的应用

    2022-10-21 03:44:55
  • 使用Spring自定义实现IOC和依赖注入(注解方式)

    2023-09-16 04:42:35
  • Java获取视频时长及截取帧截图详解

    2022-03-28 20:52:53
  • 使用JAVA实现邮件发送功能的图文教程

    2021-09-04 17:29:36
  • C#中分部类和分部方法的应用

    2022-08-16 06:49:05
  • 最常用的1000个Java类(附代码示例)

    2023-03-25 20:29:07
  • C# 大数据导出word的假死报错的处理方法

    2022-09-25 07:19:48
  • Struts2 文件上传进度条的实现实例代码

    2023-04-20 11:13:59
  • python如何调用java类

    2022-03-13 16:11:10
  • asp之家 软件编程 m.aspxhome.com