PopupWindow
在开发项 目中,经常会用popupwindow来弹出一个供选择操作的窗口,作为一个弹出菜单一样被使用。一般这时候设置popupwindow的位置时都是设置在点击的view下面弹出展示。比如点击一个button,只要使用showAsDropDown(btn)方法,popupwindow就会贴着button的底部显示出来。如下图一样:
基本的是代码:
main_activity.xml:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.xiaxiao.showpopupwindow.MainActivity">
<Button
android:id="@+id/btn_main"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="200dp"
android:text="Hello World!" />
</RelativeLayout>
</ScrollView>
popup_view.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.xiaxiao.showpopupwindow2.MainActivity">
<Button
android:id="@+id/btn"
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="#dd6666"
android:gravity="center"
android:text="Hello World!" />
<ImageView android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@mipmap/ic_launcher"
android:background="#aaaaaa"
android:layout_weight="1"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="#dd6666"
android:gravity="center"
android:text="Hello , can you see me?"/>
</LinearLayout>
点击按钮就会弹出popupwindow:
showPop(showPop_btn)
按钮事件:
public void showPop(View anchor) {
View view = View.inflate(this, R.layout.popup_view, null);
Button btn = (Button) view.findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "how are you", Toast.LENGTH_SHORT).show();
}
});
pop = new PopupWindow(view, ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
pop.setHeight(2000);
pop.setOutsideTouchable(true);
pop.setFocusable(true);
pop.showAsDropDown(showPop_btn);
}
showAsDropDown
一般情况下使用这个方法都没有什么问题,但是当popupwindow的height过大的时候,根据官方对showAsDropDown方法的解释,popupwindow的位置就会出现”理所当然的错位”,即并不是按照我们预期的那样呈现出来了。同时,安卓发布了7.0 version24.。和版本23相比,同样的设置,23 ,24 的处理也有一些不一样了。
首先,我们看一下官方对showAsDropDown方法的解释:
Display the content view in a popup window anchored to the bottom-left
corner of the anchor view. If there is not enough room on screen to show
the popup in its entirety, this method tries to find a parent scroll
view to scroll. If no parent scroll view can be scrolled, the
bottom-left corner of the popup is pinned at the top left corner of the
anchor view.
以一个button为例,这段解释的大义是:popupwindow会在button的下面 贴着button的底部展示出来,但是当button底部到屏幕底部的高度
小于popupwindow的高度时,popupwindow就会找button的父view作为参考点,如果也没有符合的parent view ,popupwindow就会使自己的底部
贴button的顶部展示。以上就是api规定的showAsDropDown方法的行为。
区别:
version6.x 23
但是在安卓6.0 version23上,系统并没有遵循这个规则,可以说系统根本没有考虑button之外的其他view,这也是24和23版本的区别所在。popupwindow的高度不管是多大,
永远是基于button底部展示的。
在version23上:第一次我们设置popupwindow加载的view的高度时match_parent,其中的imageview自动扩展高度,同时设置popupwindow为match_parent:
这时弹出popupwindow的样子是这样的:pop = new PopupWindow(view, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
可以看出,系统首先考虑的是button到屏幕底部的高度大小是不是能装得下popupwindow,能的话,直接显示,不能的话则考虑是否可以对加载的view处理,使之能适应剩下的高度空间。
发现并不能装的下高度设置为match_parent的popupwindow,
于是在imageview高度可变的允许下,自动压缩了popupwindow的高度,使popupwindow填充了button底部到屏幕底部的高度空间,显示是正常的。
然后,我们设置popupwindow的高度为一个比较大的数值,明显超过手机屏幕高度的:2000
这时候,显示效果是这样的:pop.setHeight(2000);
可以看出来,popupwindow没有完全展示出来。但是依然是基于button 底部的。因为此时popupwindow高度是固定设置的了,
无法改变,由于version23又不会真正按照api要求来,所以popupwindow就显示的不完全了。
version7.0 24
在version24,7.0系统上,则会首先考虑加载的view的大小,然后看剩余的空间是否足够大,如果不足够大,则会执行api规定的showAsDropDown方法的行为,去寻找符合条件的父view。
也就是说 7.0系统不会出现这种现象:屏幕上还有未被popupwindow占用的空间,但是popupwindow显示的不完整。
所以这时候设置popupwindow高度为match_parent 时,button已经不符合定位条件了,这时候显示的效果是这样的:
《补图》
以上。
如有不对的地方,请指正。^_^ ^_^