PopUpWindow 的使用笔记
最接做需求的时候,碰到了 PopUpWindow,但是也没做过多了解,就是照搬别人的代码改改逻辑。后面视觉看了之后,说让我加一些动画效果,使用起来更加舒服。可是我看别人以前也没有写,于是就开始捣鼓 PopUpWindow。同时也写一篇文章记录下,后续忘了也可以查看。

相关方法解读
1)几个常用的构造方法
我们在文档中可以看到,提供给我们的PopupWindow的构造方法有九种之多,这里只贴实际 开发中用得较多的几个构造方法:
public PopupWindow (Context context)
public PopupWindow(View contentView, int width, int height)
public PopupWindow(View contentView)
public PopupWindow(View contentView, int width, int height, boolean focusable)
参数就不用多解释了吧,contentView是PopupWindow显示的View,focusable是否显示焦点
2)常用的一些方法
下面介绍几个用得较多的一些方法,其他的可自行查阅文档:
setContentView(View contentView):设置PopupWindow显示的View
getContentView():获得PopupWindow显示的View
showAsDropDown(View anchor):相对某个控件的位置(正左下方),无偏移
showAsDropDown(View anchor, int xoff, int yoff):相对某个控件的位置,有偏移
showAtLocation(View parent, int gravity, int x, int y): 相对于父控件的位置(例如正中央Gravity.CENTER,下方Gravity.BOTTOM等),可以设置偏移或无偏移 PS:parent这个参数只要是activity中的view就可以了!
setWidth/setHeight:设置宽高,也可以在构造方法那里指定好宽高, 除了可以写具体的值,还可以用WRAP_CONTENT或MATCH_PARENT, popupWindow的width和height属性直接和第一层View相对应。
setFocusable(true):设置焦点,PopupWindow弹出后,所有的触屏和物理按键都由PopupWindows 处理。其他任何事件的响应都必须发生在PopupWindow消失之后,(home 等系统层面的事件除外)。 比如这样一个PopupWindow出现的时候,按back键首先是让PopupWindow消失,第二次按才是退出 activity,准确的说是想退出activity你得首先让PopupWindow消失,因为不并是任何情况下按back PopupWindow都会消失,必须在PopupWindow设置了背景的情况下 。
setAnimationStyle(int):设置动画效果
创建布局
PopUpWindow 就是一个容器,是需要编写对应的布局文件,布局比较简单具体如下:
<?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="match_parent"
android:clipChildren="false"
android:orientation="vertical">
<View
android:id="@+id/empty_view"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_weight="1"
/> <LinearLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="@color/colorPrimary"
android:orientation="vertical"
android:gravity="center_vertical"> <TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="60dp"
android:text="test" /> </LinearLayout>
</LinearLayout>
注意其中这行代码:
android:layout_weight="1"
由于其他 view 没有使用这个属性,默认为0,使用该属性的view将剩余的空间铺满。这样就相当于为我们设置了一个蒙层了。
写好布局后,需要将布局文件传到容器中去。
PopUpWindow 使用
由于相关代码比较长,直接附上完整代码,方便大家查看。
完整代码如下:
public class TestActivity extends AppCompatActivity implements View.OnClickListener {
private PopupWindow mPopupWindow;
private ViewGroup mContentView;
private Button mBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
mBtn = (Button) findViewById(R.id.result);
mPopupWindow = new PopupWindow(this);
mPopupWindow.setContentView(getContentView(this));
mPopupWindow.setHeight(ViewGroup.LayoutParams.MATCH_PARENT);
mPopupWindow.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
mPopupWindow.setClippingEnabled(false);
// 如果不设置PopupWindow的背景,有些版本就会出现一个问题:无论是点击外部区域还是Back键都无法dismiss弹框
mPopupWindow.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color
.empty_view_background)));
mPopupWindow.setOutsideTouchable(true);
mPopupWindow.setFocusable(true);
mPopupWindow.update();
mBtn.setOnClickListener(this);
}
/**
* popup window view 初始化
*
* @return View
*/
private View getContentView(Context ctx) {
mContentView = (ViewGroup) LayoutInflater.from(ctx)
.inflate(R.layout.popup, null);
View emptyViewAbovePanel = mContentView.findViewById(R.id.empty_view);
emptyViewAbovePanel.setOnClickListener(this);
return mContentView;
}
@Override
public void onClick(View v) {
int i = v.getId();
if (i == R.id.empty_view) {
Animation animation = AnimationUtils.loadAnimation(this, R.anim.pop_gone);
mContentView.startAnimation(animation);
animation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
mPopupWindow.dismiss();
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
} else if (i == R.id.result) {
mContentView.startAnimation(AnimationUtils.loadAnimation(this, R.anim.pop_in));
mPopupWindow.showAsDropDown(mBtn, 50, 50);
}
}
}
上面的代码设置了蒙层,出场入场的动画效果。
动画设置
出场动画文件xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="400"
android:fromXDelta="0"
android:fromYDelta="0"
android:toXDelta="0"
android:toYDelta="100%" />
</set>
进场动画文件xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="400"
android:fromXDelta="0"
android:fromYDelta="100%"
android:toXDelta="0"
android:toYDelta="0" />
</set>
为什么出场动画不用 PopUpWindow 默认动画设置呢。这是因为视觉只希望下面蓝色部分有动画效果,蒙层不需要这个动画效果。因此我们就必须添加额外的处理逻辑。如果采用默认的动画设置效果,将会使得蒙层也有动画效果。
在资源文件的values的style.xml中添加如下代码
<style name="pop_animation" parent="android:Animation">
<item name="android:windowEnterAnimation">@anim/pop_in</item>
<item name="android:windowExitAnimation">@anim/pop_gone</item>
</style>
android:windowEnterAnimation:为窗体进入时执行;
android:windowExitAnimation:为窗体退出时执行;
将其使用到PopupWindow中:
mPopupWindow.setAnimationStyle(R.style.pop_animation);
mPopupWindow.showAtLocation(view, Gravity.CENTER, 0, 0);
setAnimationStyle() 即是为 PopupWindow 添加动画的方法,由于 PopupWindow 不能像其他的 View 一样使用 ObjectAnimator, 所以使用动画需要在 style 中定义,并且使用 PopupWindow 的 setAnimationStyle() 方法。这样的话就可以使用。
蒙层的处理
除了上面的我的蒙层方法,还有其他添加蒙层的方法:
1)添加一层view
private void addMaskView(IBinder token) {
WindowManager.LayoutParams p = new WindowManager.LayoutParams();
p.width = WindowManager.LayoutParams.MATCH_PARENT;
p.height = WindowManager.LayoutParams.MATCH_PARENT;
p.format = PixelFormat.TRANSLUCENT;
p.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
p.token = token;
p.windowAnimations = android.R.style.Animation_Toast;
maskView = new View(context);
maskView.setBackgroundColor(0x7f000000);
maskView.setFitsSystemWindows(false);
maskView.setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
removeMaskView();
return true;
}
return false;
}
});
wm.addView(maskView, p);
}
然后在消失的时候进行移除:
public void dismiss() {
if (maskView != null) {
wm.removeViewImmediate(maskView);
maskView = null;
}
super.dismiss();
}
2) 透明度
还有人是直接使用透明度来实现的。
private void bgAlpha(float alpha) {
WindowManager.LayoutParams lp = ((Activity)context).getWindow().getAttributes();
lp.alpha = alpha;// 0.0-1.0
((Activity)context).getWindow().setAttributes(lp);
}
PopUpWindow 的使用笔记的更多相关文章
- PopupWindow 常用方法学习笔记
PopupWindow可以实现浮层效果,而且可以自定义显示位置,出现和退出时的动画. 首先解析一个View LayoutInflater inflater = getLayoutInflater(); ...
- 【转】Android开发笔记(序)写在前面的目录
原文:http://blog.csdn.net/aqi00/article/details/50012511 知识点分类 一方面写写自己走过的弯路掉进去的坑,避免以后再犯:另一方面希望通过分享自己的经 ...
- android学习笔记17——对话框(PopupWindow)
PopupWindow ==> PopupWindow可创建类似对话框的窗口,使用其创建对话框窗口的操作步骤: 1.调用PopupWindow构造器构造PopupWindow对象: 2.调用Po ...
- Android 高级UI设计笔记19:PopupWindow使用详解
1. PopupWindow使用 PopupWindow这个类用来实现一个弹出框,可以使用任意布局的View作为其内容,这个弹出框是悬浮在当前activity之上的. 2. PopupWindow使用 ...
- android开发关于popupwindow显示关闭的笔记
一.方法一: popupWindow.setFocusable(false); //这样popupWindow无法获得焦点,无法处理popupWindow中的事件 设置MainActivity的onT ...
- [Android学习笔记]PopupWindow的使用
什么时候使用PopupWindow? 当业务需求的交互形式需要在当前页弹出一个简单可选项UI与用户进行交互时,可使用PopupWindow完成此功能开发 Android Dev API Doc Pop ...
- 安卓笔记-- popupwindow back键不消失的问题
// 可能是一个bug ,如果不设置背景,触摸焦点外和back键都不会消失,需如下设置,并不会影响你的背景 popupWindow.setBackgroundDrawable(new ...
- 安卓学习笔记:使用PopupWindow创建简单菜单
PopupWindow是一个弹出式窗口,它可以展示任意View.他会浮在当前窗口的上方展示. 下面看代码: public class MyActivity extends Activity { pri ...
- PopupWindow学习笔记
最近写程序第一次用到了PopupWindow,便简单了学习了一下.特此记下自己的收获.PopupWindow是一种悬浮框,比AlertDialog要灵活的多.先简单了实现一个PopWindow的效果, ...
随机推荐
- 解决多字段联合逻辑校验问题【享学Spring MVC】
每篇一句 不要像祥林嫂一样,天天抱怨着生活,日日思考着辞职.得罪点说一句:"沦落"到要跟这样的人共事工作,难道自己身上就没有原因? 前言 本以为洋洋洒洒的把Java/Spring数 ...
- Python模块之pexpect
一.pexpect模块介绍 Pexpect使Python成为控制其他应用程序的更好工具.可以理解为Linux下的expect的Python封装,通过pexpect我们可以实现对ssh,ftp,pass ...
- 剑指offer总结一:字符、数字重复问题
问题1:字符串中第一个不重复的字符 题目描述 请实现一个函数用来找出字符流中第一个只出现一次的字符.例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是" ...
- Redis----NoSql数据库笔记
介绍:Redis 是一个开源的使用 ANSI C 语言编写.遵守 BSD 协议.支持网络.可基于内存亦可持久化的日志型.Key-Value 数据库,并提供多种语言的 API的非关系型数据库. 传统数据 ...
- Python中模块与包的导入(朴实易懂版的总结)
这几天,被python包与模块的导入问题,折磨的不行,以前想的很简单,其实不然,经查资料研究,特总结如下: 基本注意点 模块:一般指一个py文件:包:含有许多py文件的文件夹,含有 或不含有(Pyth ...
- AI芯片:高性能卷积计算中的数据复用
随着深度学习的飞速发展,对处理器的性能要求也变得越来越高,随之涌现出了很多针对神经网络加速设计的AI芯片.卷积计算是神经网络中最重要的一类计算,本文分析了高性能卷积计算中的数据复用,这是AI芯片设计中 ...
- python 14 装饰器
目录 装饰器 1. 开放封闭原则 装饰器 1. 开放封闭原则 扩展是开放的,增加新的功能:修改源码(修改已经实现的功能)是封闭的. 在不改变源码及调用方式的前提下额外增加新的功能. # 版一: imp ...
- [Python] Django框架入门3——深入视图
说明: 本文主要深入了解视图(views.py),涉及路由配置.定义视图.Request对象.Response对象.状态保持等. 一.路由配置 1.配置位置(settings.py 的 ROOT_UR ...
- 原生js之Ajax
1.什么是Ajax? 全称:Asynchronous JavaScript and XML (异步的 JavaScript和 xml),是前后端数据交互的一种技术(前端通过 Ajax 发送http请 ...
- JavaScript入门之AJAX:原生ajax
背景 传统的Web应用允许用户端填写表单(form),当提交表单时就向网页服务器发送一个请求.服务器接收并处理传来的表单,然后送回一个新的网页,但这个做法浪费了许多带宽,因为在前后两个页面中的大部分H ...