PopupWindow遇到的几个坑

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013055213/article/details/67650535


主要介绍popupWindow的弹出位置,popupWindow的大小,什么时候弹出,蒙版的设置,蒙版后面不可以点击,禁用返回键,点击两次退出应用.
1. popupWindow的弹出位置
最近版本迭代需要使用popupWindow弹出一个界面,之前popupWindow都是现对于某个控件弹出,如何设置popupWindow在整个布局中弹出呢?查了popupWindow设置位置的几个方法,有

popupwindow设置位置的几种方法其中showAsDropDown是相对于某个控件的位置,showAtLocation是将popupWindow设置在自定义的控件上,设置布局位置及x,y的偏移量.
popupWindow的showAtLocation的方法
然后我选择了第二种方式,把pop弹出页面的更布局作为显示的view,设置居中显示,偏移量x为0,y就是整个窗口的大小-当前跟布局的大小.其实就是状态栏的大小.

mHeight = mRl_root.getHeight();//根布局的高度
WindowManager wm = this.getWindowManager();
int height = wm.getDefaultDisplay().getHeight();//整个屏幕的高度
2.popupWindow窗体的大小 因为popupWindow有自己的页面,所以我使用自定义的popupWindow,这就涉及到popupWindow的大小设置.
WindowManager wm= (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics metrics= new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(metrics);
mWidth=metrics.widthPixels;

开始我使用这个方法设置popupWindow的宽高,但是总是下面的一点没有显示出来,后来发现这种方式获取的宽高是整个屏幕的,所以后来在构造方法中传递一个参数就是根布局的高度,问题就迎刃而解了.

3.popupWindow在一进界面就弹出.
由于功能需要,我想要popupWindow已进入页面就弹出,刚开始在onCreate(),onResume()方法中调用都失败了,空指针异常,这是必须的,因为这时根布局view还没有初始化完毕,拿不到宽和高.详细的可以看一下老罗的博客 Activity对象view视图创建过程.之后我 就用onWindowFocusChanged()方法,可以弹出是可以弹出了,但是一直弹出,根本停不下来,我知道了,因为焦点一直在改变.继续探寻,发现了onAttachedToWindow()发现这个方法,该方法是有效,但是不可以直接调用,必须添加一个Handler才可以,这块目前还没有弄明白,欢迎探讨.

@Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                honestState();//弹出popupWindow
            }
        },20);

    }
可以看一下这篇博客 [onAttachedToWindow()在Activity生命周期中的位置及作用](http://blog.csdn.net/guxiao1201/article/details/41517871) 4.popupwindow添加阴影 为了pop弹出的效果更加完美,我们要求给pop添加阴影,我使用下面的这种方式添加的阴影.
    WindowManager.LayoutParams lp = getWindow().getAttributes();
    lp.alpha = 0.3f;
    getWindow().setAttributes(lp);
当弹出pop是设置成0.3f,pop退回是设置成1.0f,但是还不够完善.还需要不遮盖状态栏,这个没有想出好办法,我只是在动画的执行时间结束后,将屏幕的透明度设置成1.0f了.如果大家有什么好建议欢迎分享.
new Handler(new Handler.Callback() {
            @Override
            public boolean handleMessage(Message msg) {
                WindowManager.LayoutParams lp = getWindow().getAttributes();
                lp.alpha = 1.0f;
                getWindow().setAttributes(lp);
                return false;
            }
        }).sendEmptyMessageDelayed(0, 500);
5.今天又遇到一个,想要禁用返回键,强制执行popupWindow的按键,开始设置activity的onKeyDown事件没有效果,后来发现是因为popupWindow的setFocusable(true);把他隐藏掉或者设置成false就可以了,同时在activity的onKeyDown方法.
// 双击退出程序
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if (myPopupWindow != null && myPopupWindow.isShowing()) {
                return true;
            }
            if (count == 0) {
                Toast.makeText(this,"再按一下退出应用",Toast.LENGTH_SHORT).show();
            }
            count++;
            if (count == 2) {
                //关闭应用
                ActivityStackControlUtil.exitApp();
                finish();
            }

            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

这样就实现了禁用的功能,此外还添加了一个双击退出程序的功能,通过遍历activity集合,将所有的activity都关闭掉,最终结束应用.

6.看来是要和popupWindow杠上了,好多bug出现在它身上,不过这样我就可以更加熟悉他.说一下我的新问题吧,popupWindow退出页面的时候总是可以点击后面的按钮,我想禁用掉,试了很多方式都有点到的概率.比如加快页面跳转的速度,不可以;检测popupWindow是否正在展示也不可以,因为只要pop执行dismiss(),就表示不再展示了,即时动画没有执行完成.后来想到了dialog,这是个好控件啊,覆盖全屏,拦截点击事件,于是乎,我干脆使用dialog来做蒙版,不用之前的方法了.上代码吧!

private Dialog myDialog;
myDialog = new Dialog(this, R.style.translucent_dialog);
WindowManager.LayoutParams lp = myDialog.getWindow().getAttributes();
lp.alpha = 0.3f;
当弹出pop是就myDialog.show(); pop弹出了就myDialog.dismiss(); pop退出时也展示dialog,并将隐藏dialog做了一个延迟,在执行完动画之后在隐藏,于是问题就解决了.
myDialog.show();
//强制签署就退出应用
mRl_root.postDelayed(new Runnable() {
      @Override
        public void run() {
            Intent intent = new Intent(MainActivity.this, LoginActivity.class);
            MainActivity.this.setResult(800, intent);
            MainActivity.this.finish();
        }
    }, 500);
    new Handler().postDelayed(new Runnable()
     {
         public void run()
         {
             myDialog.dismiss();
         }
     }, 600);

ok,问题总结完了,希望可以帮助到你.随着问题不断的出现慢慢的总结,之后遇到解决起来就容易了,听说Activity做弹窗比pop的问题少,下次用Activity做一下.关于这个案例的demo我放到github上了,有兴趣的可以下载.
popupWindow的demo连接
也可以直接在csdn中下载,popupWindow的Demo下载

猜你喜欢

转载自blog.csdn.net/u013055213/article/details/67650535
今日推荐