在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 @Override 24 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 * 初始化PopupWindow 35 */ 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以外的地方關閉PopupWindow 42 mPopWin.setFocusable(true); //獲取焦點 43 } 44 45 class ButtonClickListener implements View.OnClickListener { 46 47 @Override 48 public void onClick(View v) { 49 //點擊在按鈕的中下方彈出mPopWin 50 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; //因為相對於按鈕的下方,所以該值為0 62 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 @Override 24 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 * 初始化PopupWindow 35 */ 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以外的地方關閉PopupWindow 43 mPopWin.setFocusable(true); //獲取焦點 44 } 45 46 class ButtonClickListener implements View.OnClickListener { 47 48 @Override 49 public void onClick(View v) { 50 //點擊在按鈕的中下方彈出mPopWin 51 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; //因為相對於按鈕的下方,所以該值為0 63 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行代碼出現空指針錯誤,導致程序崩潰。希望看到此文章的人在開發中需要注意。