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     @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行代碼出現空指針錯誤,導致程序崩潰。希望看到此文章的人在開發中需要注意。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM