popupwindow影响状态栏_Android 开发 PopupWindow弹窗

本文介绍了Android中的PopupWindow组件,包括其基本用法、应用场景、配置参数详解,以及如何处理影响状态栏的问题。通过示例代码展示了如何创建、设置和展示PopupWindow,还提到了在Android 7.0以上版本中解决showAsDropDown方法失效的解决方案。
摘要由CSDN通过智能技术生成

简介

PopupWindow,顾名思义弹窗.PopupWindow是与AlertDialog在形式上类似的弹窗功能,都是为了在activity最上层显示一个弹窗.但是区别是PopupWindow可以自定义出现的位置,并且可以添加入自己需要的View或者导入自己写好的xml布局

应用场景

在很多场景下都可以见到它。例如ActionBar/Toolbar的选项弹窗,一组选项的容器,或者列表等集合的窗口等等。

简单的Demo

为了了解基本的流程,我们来一个最简单demo演示一下.

创建流程:

用LayoutInflater获得xml布局View .或者直接在代码上new一个View

实例化一个PopupWindow,将View在实例化作为参数传入

配置PopupWindow参数

代码:

@Overrideprotected voidonCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main2);

TextView textView= new TextView(Main2Activity.this);

textView.setText("测试文本");final PopupWindow popupWindow = new PopupWindow(textView,200,300);//参数为1.View 2.宽度 3.高度

popupWindow.setOutsideTouchable(true);//设置点击外部区域可以取消popupWindow

mTestButton=(Button)findViewById(R.id.test_btn);

mTestButton.setOnClickListener(newView.OnClickListener() {

@Overridepublic voidonClick(View v) {

popupWindow.showAsDropDown(mTestButton);//设置popupWindow显示,并且告诉它显示在那个View下面

}

});

}

效果图:

PopupWindow的配置参数详解

设置内容View

setContentView(View contentView)

除了正常在实例化PopupWindow的时候直接将view传入也可以用这个方法在实例化后重新配置需要的view

设置PopupWindow宽度与高度

setWidth(intwidth)

setHeight(int height)

除了正常实例化的时候传入宽度与高度,也可以用这个2个方法在实例化后在重新配置需要的宽度与高度

设置PopupWindow背景

setBackgroundDrawable(Drawable background)

final PopupWindow popupWindow = new PopupWindow(textView,200,300);

popupWindow.setOutsideTouchable(true);

popupWindow.setBackgroundDrawable(getResources().getDrawable(R.drawable.ic_launcher_background));//设置背景

mTestButton=(Button)findViewById(R.id.test_btn);

mTestButton.setOnClickListener(newView.OnClickListener() {

@Overridepublic voidonClick(View v) {

popupWindow.showAsDropDown(mTestButton);

}

});

设置外部点击退出

setOutsideTouchable(boolean touchable)

这个我在上面的代码已经演示过了

设置PopupWindow可聚焦

setFocusable(boolean focusable)

除了一般的聚焦选中功能,还有一个用处重点!重点!重点!设置了可聚焦后,返回back键按下后,不会直接退出当前activity而是先退出当前的PopupWindow.

设置弹窗弹出的动画高度

setElevation(float elevation)

原本没有设置,弹窗的弹出动画效果位置就只会在控件附件,但是设置后弹窗的起始动画位置就变更远了.请看下面的效果图:

popupWindow.setElevation(1000f);//我将动画位置设置为1000f

设置显示方法

显示提供了两种形式:

showAtLocation()显示View的内部在指定位置()

有两个方法重载:

这个属性一般使用在在整个Activity的window里显示,也就是在整个屏幕内,这个也支持在指定View的内部找到锚点.

例子1:如果你需要在一个布局的里面的下方显示就只需要设置属性为

popupWindow.showAtLocation(view,Gravity.BOTTOM,0,0);

例子2:如果你需要在Activity的window里显示的下方显示就需要设置属性为:

popupWindow.showAtLocation(activity.getWindow().getDecorView(),Gravity.BOTTOM,0,0);

public void showAtLocation(View parent, int gravity, int x, inty)public void showAtLocation(IBinder token, int gravity, int x, int y)

showAsDropDown()显示在一个参照物View的外部周围

有三个方法重载:

注意!这里参照物View的周围,使用这个方法是无法在View的内部找到锚点,它的锚点都是围绕者View的外部四周

public voidshowAsDropDown(View anchor)public void showAsDropDown(View anchor, int xoff, intyoff)public void showAsDropDown(View anchor, int xoff, int yoff, int gravity)

带Gravity参数的方法是API 19新引入的。

这里的xoff与yoff是对应view的坐标偏移量,对应的初始坐标位置是view的左下角.

请注意!在实际使用showAsDropDown()方法的时候,如果只使用showAsDropDown(View anchor, int xoff, intyoff),这个形参会出现在一些品牌的机型上出现一些问题。原因是有些机型初始坐标其实不一定在左下角,而是在左上角。所以,你这个时候设置yoff值就会出现2种不同去情况。怎么解决这个问题呢? 就是尽量使用showAsDropDown(View anchor, int xoff, int yoff, int gravity),这个形参主动设置第4个int gravity的值,来确定初始坐标的位置。

这里我们用一个demo演示一下,假设我现在需要把显示位置移动到目标控件的右上角就需要如下代码:

popupWindow.showAsDropDown(mTestButton,mTestButton.getWidth(),-mTestButton.getHeight())

设置PopupWindow叠放效果

setOverlapAnchor(true);

当然你把PopupWindow的位置设置到可以完全覆盖你指定位置显示PopupWindow的view时,如果设置这个方法为true,那么你无论如何都无法覆盖这个view始终会让这个view漏出一小部分,如效果图所示:

设置PopupWindow可触摸

setTouchable(true);

设置false后,将会阻止PopupWindow窗口里的所有点击事件

设置PopupWindow监听拦截指定触摸事件

popupWindow.setTouchInterceptor(newView.OnTouchListener() {

@Overridepublic booleanonTouch(View v, MotionEvent event) {

//如果这里设置返回true,说明你会消耗这个触摸事件,不会向下传递到内容view里return false;

}

});

设置PopupWindow覆盖状态栏或者超过屏幕尺寸

允许弹出窗口扩展到屏幕范围之外。默认情况下,窗口被裁剪到屏幕边界。将其设置为false将允许精确定位窗口

popupWindow.setClippingEnabled(false);

设置PopupWindow监听取消事件

popupWindow.setOnDismissListener(newPopupWindow.OnDismissListener() {

@Override

public voidonDismiss() {

}

});

一些问题总结

解决Android7.0调用showAsDropDown方法失效问题

原理是重写showAsDropDown,将PopupWindow对话框的高度设置成整个屏幕这么大,然后在减去这View指定的底部坐标值。有点治标不治本的味道。

但是,在个别对话框宽度是屏幕的宽度,但是高度是某个View下边与屏幕底部的长度的时候有很好的实现。

如图所示:

没有对话框的时候

有对话框的时候

@Overridepublic voidshowAsDropDown(View anchor) {if(Build.VERSION.SDK_INT >= 24) {

Rect rect= newRect();

anchor.getGlobalVisibleRect(rect);

DisplayMetrics outMetrics= newDisplayMetrics();

Context context=anchor.getContext();

((Activity) context).getWindowManager().getDefaultDisplay().getRealMetrics(outMetrics);int h = outMetrics.heightPixels -rect.bottom;

setHeight(h);

}super.showAsDropDown(anchor);

}

end

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值