首页 > 代码库 > Android中的PopupWindow中getWidth、getHeight为0或者-2

Android中的PopupWindow中getWidth、getHeight为0或者-2

  在Android开发中,需要用到PopupWindow这个类。在初始化完成,显示之前,都需要获得这个对象的width,height去计算popupWindow弹出的位置。

这个时候会发现取得的width和height都是-2;使用popupWindow.getContentView().getMeasuredWidth()和popupWindow.getContentView().getMeasuredHeight()取得的值都是0。如下面的代码:

activity_main.xml

 1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3               android:orientation="vertical" 4               android:layout_width="fill_parent" 5               android:layout_height="fill_parent" 6         > 7  8     <Button 9             android:layout_width="wrap_content"10             android:layout_height="wrap_content"11             android:text="New Button"12             android:id="@+id/button"13             android:layout_gravity="center_horizontal"/>14 </LinearLayout>

 

popwin_layout.xml

 1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3               android:orientation="vertical" 4               android:layout_width="match_parent" 5               android:layout_height="match_parent"> 6     <ImageView 7             android:layout_width="wrap_content" 8             android:layout_height="wrap_content" 9             android:src="@drawable/ic_launcher"/>10 </LinearLayout>

 

MyActivity.class

 1 package com.example.popwinsize; 2  3 import android.app.Activity; 4 import android.graphics.drawable.BitmapDrawable; 5 import android.os.Bundle; 6 import android.text.Layout; 7 import android.util.Log; 8 import android.view.LayoutInflater; 9 import android.view.View;10 import android.view.ViewGroup;11 import android.widget.Button;12 import android.widget.PopupWindow;13 14 public class MyActivity extends Activity {15 16     private PopupWindow mPopWin;17 18     private Button mButton;19 20     /**21      * Called when the activity is first created.22      */23     @Override24     public void onCreate(Bundle savedInstanceState) {25         super.onCreate(savedInstanceState);26         setContentView(R.layout.activity_main);27         mButton = (Button) findViewById(R.id.button);28         mButton.setOnClickListener(new ButtonClickListener());29 30         initPopupWindow();31     }32 33     /**34      * 初始化PopupWindow35      */36     private void initPopupWindow() {37         View contentView = LayoutInflater.from(this).inflate(R.layout.popwin_layout, null);38         mPopWin = new PopupWindow(contentView,39                 ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);40         mPopWin.setBackgroundDrawable(new BitmapDrawable());    //设置背景,否则setOutsideTouchable无效41         mPopWin.setOutsideTouchable(true);                      //设置点击PopupWindow以外的地方关闭PopupWindow42         mPopWin.setFocusable(true);                             //获取焦点43     }44 45     class ButtonClickListener implements View.OnClickListener {46 47         @Override48         public void onClick(View v) {49             //点击在按钮的中下方弹出mPopWin50 51             int btnWidth = v.getMeasuredWidth();52             int btnHeight = v.getMeasuredHeight();53 54             int popWidth = mPopWin.getContentView().getMeasuredWidth();55             int popHeight = mPopWin.getContentView().getMeasuredHeight();56             Log.i("Button.size", "width=" + btnWidth + "; height=" + btnHeight);57             Log.i("PopupWindow.size", "width=" + popWidth + "; height=" + popHeight);58             //mPopWin.showAsDropDown(v);    //这个是在按钮的下方出现,x值与按钮的x值相等59 60             int xoff = (int)((float)(btnWidth - popWidth)/2);    //PopupWindow的x偏移值61             int yoff = 0;                                        //因为相对于按钮的下方,所以该值为062 63             mPopWin.showAsDropDown(v, xoff, yoff);64         }65     }66 }

这个时候你会发现,出现的效果并不是您想要的效果,是在按钮是右下方出现

LogCat捕获的结果是:

   I/Button.size﹕ width=176; height=72
   I/PopupWindow.size﹕ width=0; height=0

出现这个的原因就是因为PopupWindow的尺寸拿不到,因为内容的View的width和height都是wrap_content,所以在PopupWindow里面的contentView还没被绘制出来的时候,这两个值都还是0。

如果直接调用PopupWindow的getWidth()和getHeight(),会发现拿到的都是ViewGroup.LayoutParams.WRAP_CONTENT的值 -2;

 

解决的方法就是在初始化contentView的时候,强制绘制contentView,并且马上初始化contentView的尺寸。这里只需要一句代码即可

看下面的MyActivity.class的第38行代码:

 1 package com.example.popwinsize; 2  3 import android.app.Activity; 4 import android.graphics.drawable.BitmapDrawable; 5 import android.os.Bundle; 6 import android.text.Layout; 7 import android.util.Log; 8 import android.view.LayoutInflater; 9 import android.view.View;10 import android.view.ViewGroup;11 import android.widget.Button;12 import android.widget.PopupWindow;13 14 public class MyActivity extends Activity {15 16     private PopupWindow mPopWin;17 18     private Button mButton;19 20     /**21      * Called when the activity is first created.22      */23     @Override24     public void onCreate(Bundle savedInstanceState) {25         super.onCreate(savedInstanceState);26         setContentView(R.layout.activity_main);27         mButton = (Button) findViewById(R.id.button);28         mButton.setOnClickListener(new ButtonClickListener());29 30         initPopupWindow();31     }32 33     /**34      * 初始化PopupWindow35      */36     private void initPopupWindow() {37         View contentView = LayoutInflater.from(this).inflate(R.layout.popwin_layout, null);38         contentView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);39         mPopWin = new PopupWindow(contentView,40                 ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);41         mPopWin.setBackgroundDrawable(new BitmapDrawable());    //设置背景,否则setOutsideTouchable无效42         mPopWin.setOutsideTouchable(true);                        //设置点击PopupWindow以外的地方关闭PopupWindow43         mPopWin.setFocusable(true);                                //获取焦点44     }45 46     class ButtonClickListener implements View.OnClickListener {47 48         @Override49         public void onClick(View v) {50             //点击在按钮的中下方弹出mPopWin51 52             int btnWidth = v.getMeasuredWidth();53             int btnHeight = v.getMeasuredHeight();54 55             int popWidth = mPopWin.getContentView().getMeasuredWidth();56             int popHeight = mPopWin.getContentView().getMeasuredHeight();57             Log.i("Button.size", "width=" + btnWidth + "; height=" + btnHeight);58             Log.i("PopupWindow.size", "width=" + popWidth + "; height=" + popHeight);59             //mPopWin.showAsDropDown(v);    //在按钮的下方出现,x值与按钮的x值相等60 61             int xoff = (int)((float)(btnWidth - popWidth)/2);    //PopupWindow的x偏移值62             int yoff = 0;                                        //因为相对于按钮的下方,所以该值为063 64             mPopWin.showAsDropDown(v, xoff, yoff);65         }66     }67 }

这个时候LogCat打印出来的结果:

   I/Button.size﹕ width=176; height=72
   I/PopupWindow.size﹕ width=72; height=72

效果如下:

另外一个点需要注意:popwin_layout.xml的根Layout必须为LinearLayout;如果为RelativeLayout的话,会在第38行代码出现空指针错误,导致程序崩溃。希望看到此文章的人在开发中需要注意。

Android中的PopupWindow中getWidth、getHeight为0或者-2