PopupWindow的使用

在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=72I/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=72I/PopupWindow.size﹕ width=72; height=72

效果如下:

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

案例二:

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/grid"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:rowCount="4"
    android:background="@drawable/share_bg_blue"
    android:paddingTop="10dp"
    android:paddingLeft="8dp"
    android:paddingRight="8dp"

    android:paddingBottom="10dp"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/faceBook_img"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/icon_facebook" />

    <ImageView
        android:id="@+id/twitter_img"
        android:layout_marginTop="10dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/icon_twitter" />

    <ImageView
        android:id="@+id/instagram_img"
        android:layout_marginTop="10dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/icon_instagram" />

    <ImageView
        android:id="@+id/tubmlr_img"
        android:layout_marginTop="10dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/icon_tumblr" />
</GridLayout>

逻辑代码:

 PopupWindow popupWindow = new PopupWindow();
        View addCourseView = LayoutInflater.from(context).inflate(R.layout.share_my_course, null);
        addCourseView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
        popupWindow.setContentView(addCourseView);
        popupWindow.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
        popupWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
        popupWindow.setBackgroundDrawable(new ColorDrawable());
        popupWindow.setFocusable(true);
        popupWindow.setOutsideTouchable(true);
        //获取屏幕的宽高
        DisplayMetrics metric = new DisplayMetrics();
        getActivity().getWindowManager().getDefaultDisplay().getMetrics(metric);
        int width = metric.widthPixels;     // 屏幕宽度(像素)
        int height = metric.heightPixels;   // 屏幕高度(像素)
        float density = metric.density;      // 屏幕密度(0.75 / 1.0 / 1.5)
        int densityDpi = metric.densityDpi;  // 屏幕密度DPI(120 / 160 / 240)
//        int i = width - drawerright.getWidth();
        int i = drawer.getWidth() - drawerright.getWidth() - popupWindow.getContentView().getMeasuredWidth();
        Log.e("=========", "=====drawer.getWidth()==" + drawer.getWidth());
        Log.e("=========", "=====drawerright.getWidth()==" + drawerright.getWidth());
        Log.e("=========", "=====addCourseView.getWidth()==" + addCourseView.getWidth());
        Log.e("=========", "=====popupWindow.getWidth()==" + popupWindow.getContentView().getMeasuredWidth());
        Log.e("=========", "=====i==" + i);
        popupWindow.showAtLocation(listview, Gravity.LEFT | Gravity.CENTER_VERTICAL, i, 0);
        addCourseView.findViewById(R.id.faceBook_img).setOnClickListener(new MyListener());
        addCourseView.findViewById(R.id.twitter_img).setOnClickListener(new MyListener());
        addCourseView.findViewById(R.id.instagram_img).setOnClickListener(new MyListener());
        addCourseView.findViewById(R.id.tubmlr_img).setOnClickListener(new MyListener());
    }

    class MyListener implements View.OnClickListener {

        @Override
        public void onClick(View view) {
            switch (view.getId()) {
                case R.id.faceBook_img:
                    Toast.makeText(context, "faceBook", Toast.LENGTH_SHORT).show();
                    showShare(true, Facebook.NAME);
                    break;
                case R.id.twitter_img:
                    Toast.makeText(context, "twitter", Toast.LENGTH_SHORT).show();
                    showShare(true, Twitter.NAME);
                    break;
                case R.id.instagram_img:
                    Toast.makeText(context, "instagram", Toast.LENGTH_SHORT).show();
                    showShare(true, Instagram.NAME);
                    break;
                case R.id.tubmlr_img:
                    Toast.makeText(context, "tubmlr", Toast.LENGTH_SHORT).show();
                    showShare(true, Tumblr.NAME);
                    break;
            }
        }
    }

    private void showShare(boolean silent, String platform) {
        OnekeyShare oks = new OnekeyShare();
        oks.setTitle("Super Classmate");
        oks.setText("Super Classmate" + " http://www.mob.com");
        oks.setDialogMode();
        oks.disableSSOWhenAuthorize();
        if (platform != null) {
            oks.setPlatform(platform);
        }
        oks.setShareContentCustomizeCallback(new ShareContentCustomizeCallback() {
            @Override
            public void onShare(Platform platform, Platform.ShareParams paramsToShare) {

            }
        });
        oks.show(context);
    }
运行结果:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值