关于PopupWindow的简单说明
来源:互联网 发布:linux怎么看内存大小 编辑:程序博客网 时间:2024/05/20 11:37
最新项目中不仅用到了WindowManager来在机顶盒全屏直播状态下按“菜单”键动态添加一个View,该View包含一个ListView用来显示节目列表;同时也用到了PopupWindow实现了下面的一个t9输入法的页面:
点击1到9的某个按钮时候:
具体实现方法就不赘述了,就是PopupWindow的简单应用。本篇博客就是简单的说明的是PopupWindow的实现原理。
PopupWindow不是一个Window,只是一个普通的Java类(它的直接父类是Object),在分析之前先说一个既定事实:PopupWindow是通过WindowManager对象来添加和删除View的。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
setContentView并不像Activity中一样调用了就可以在页面中把PopupWindow在页面中显示出来。因为上面的代码就没有调用mWindowManager把要显示的View添加到WindowManager中。
其实PopupWindow还真找不到如下的一个方法来快速的显示自定义LayoutParams的View:
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
如果要显示PopupWindow的话还需要调用如下三个方法之一:showAsDropDown(View anchor),showAsDropDown(View anchor, int xoff, int yoff),showAtLocation(View parent, int gravity, int x, int y)。这三个方法最终都会调用invokePopup这个方法来让页面中最终显示PopupWindow,其实这个方法最主要的也就是调用了mWindowManager.addView方法而已,需要注意的是这个方法是private的,外部无法访问:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
不过在调用showAtLocation和invokPopup之间又是经过怎么样的处理呢?下面先看看showAtLocation这个方法都做了什么:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
showAtLocation方法中有调用了一个重要的方法preparePopup,该法主要是用来初始化mPopupView,而invokePopup方法中mWindowManager.addView添加的View就是mPopupView这个View:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
注意上面初始化mPopupView的方式有两种,如果mBackgroundd!=null,该方法变量可以通过setBackgroundDrawable来设置,那么mPopupView 就是PopupViewContainer ,PopupViewContainer 是一个FrameLayout的子类,主要是重写了dispatchKeyEvent来处理返回键,当用户按返回键的时候就调用dimiss来关闭PopupWindow:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
使用PopupViewContainer其实很简单,添加如下一段代码即可:
popupWindow.setBackgroundDrawable(new ColorDrawable(0));
这样按返回键的时候就可以自动关闭PopupWindow.
当然如果在你的应用程序中没有调用setBackgroundDrawable方法的话,那么在处理返回键关闭PopupWindow的时候就需要为你的contentView设置onKeyListener方法或者模仿PopupViewContainer的dispatchKeyEvent来自定义一个View了。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
同时PopupWindow也提供了几个update重载方法,除了update()这个无参数方法之外其余的几个update最终都调用了update(int x, int y, int width, int height, boolean force);
不过这些update方法真正在页面上呈现出更新效果的还是因为调用了windowManager的updateViewLayout(View,LayoutParam)方法:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
文章最后说一下在弹出PopupWindow的时候按home键的处理问题,如果你按home键的需求是关闭掉对应的Activity的话,你需要监听home键当用户按home键的时候直接调用对应Activity的finish()方法即可,但是如果此时你的页面有PopupWindow存在,如果不做一个处理的话会报如下错误:
解决这个问题的方法也很简单,重写Activity的finish方法,在该方法里面调用如下代码即可:
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
其实我们可以发现不论对View添加、删除还是更新操作最终就是通过WindowManager来完成的,这点需要注意,关于WindowManager的一些简单总结可以看《WindowManager杂谈 》!到此为止本篇博客就结束了,还有一些没有讲到,比如showAtLoaction方法中IBinder参数的作用是用来干什么的?
- 关于PopupWindow的简单说明
- 关于PopupWindow的简单说明
- 关于synonym的简单说明
- 关于oozie的简单说明
- 简单的PopupWindow
- 简单的PopupWindow
- popupwindow的简单使用
- PopupWindow的简单用法
- PopupWindow的简单用法
- PopupWindow的简单使用
- PopupWindow 的简单使用
- PopupWindow的简单使用
- popupWindow的简单使用
- Popupwindow 的简单使用
- PopupWindow的简单使用
- PopupWindow的简单用法
- PopupWindow的简单使用
- PopupWindow的简单用法
- bash shell test条件测试[[ ]]和[ ]异同小结
- C++开发工程师课程第一周笔记 GeekBank
- 最短路模板
- SQL注入这个坑
- ECharts地图应用定位
- 关于PopupWindow的简单说明
- 微信小程序创建时:当前开发者未绑定此appid,请到mp后台操作
- iOS转场动画总结
- 学习HTML第一天
- 原生javascript设置获取行间样式及非行间样式的写法
- .\Objects\5.sct(7): error: L6236E: No section matches selector - no section to be FIRST/LAST.
- Android Studio 比较有用的插件。
- vs2010 error C2470: “ClassA”: 看起来像函数定义,但没有参数列表;跳过明显的函数体
- CoreData-基本数据操作(增删改查)