在Android开发中,需要用到PopupWindow这个类。在初始化完成,显示之前,都需要获得这个对象的width,height去计算popupWindow弹出的位置。
这个时候会发现取得的width和height都是-2;使用popupWindow.getContentView().getMeasuredWidth()和popupWindow.getContentView().getMeasuredHeight()取得的值都是0。如下面的代码:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout 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" tools:context="com.jcdh.jcli.mypopupwindow.MainActivity"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="ShowPopupWindow" android:onClick="showPopupWindow" android:id="@+id/button2" android:layout_centerVertical="true" android:layout_centerHorizontal="true" /> </RelativeLayout>
popupwindow.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/custom_info_bubble"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="姓名:李VV 性别:男 出生日期:1990/12/12 12:10:05 所在地:北京" android:textSize="15sp" android:id="@+id/textView" android:layout_gravity="center_horizontal" /> </LinearLayout>
MainActitivty:
public class MainActivity extends Activity { private PopupWindow popupWindow; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initPopupWindow(); } /** * 初始化PopupWindow */ private void initPopupWindow() { View <span style="background-color:#40332b;">view</span>= LayoutInflater.from(this).inflate(R.layout.popupwindow, null); popupWindow = new PopupWindow(view, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); //设置背景,否则setOutsideTouchable无效 popupWindow.setOutsideTouchable(true); //设置点击PopupWindow以外的地方关闭PopupWindow popupWindow.setFocusable(true); //获取焦点 } public void showPopupWindow(View v) { //点击在按钮的中上方弹出popupWindow int btnWidth = v.getMeasuredWidth(); int btnHeight = v.getMeasuredHeight(); int popWidth = popupWindow.getContentView().getMeasuredWidth(); int popHeight = popupWindow.getContentView().getMeasuredHeight(); int xoff = (int)((float)(btnWidth - popWidth)/2);//PopupWindow的x偏移值 int yoff = popHeight+btnHeight ; //因为相对于按钮的上方,所以该值为负值 popupWindow.showAsDropDown(v,xoff,-yoff); } }这时出现的效果并不是想要的效果,是在按钮是右上方出现
出现这个的原因就是因为PopupWindow的尺寸拿不到,因为内容的View的width和height都是wrap_content,所以在PopupWindow里面的contentView还没被绘制出来的时候,这两个值都还是0。
如果直接调用PopupWindow的getWidth()和getHeight(),会发现拿到的都是ViewGroup.LayoutParams.WRAP_CONTENT的值 -2;
解决的方法就是在初始化popupwindow view的时候,强制绘制view,并且马上初始化view的尺寸。这里只需要一句代码即可,加在
<span style="font-size:14px;">initPopupWindow 第二行:</span>
view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);最终效果:
另外一个点需要注意:popwin_layout.xml的根Layout必须为LinearLayout;如果为RelativeLayout的话,会在第38行代码出现空指针错误,导致程序崩溃。希望看到此文章的人在开发中需要注意。