popmenu 和popWindow

资料来源

https://blog.csdn.net/a379992210/article/details/48423923

https://blog.csdn.net/shanxuyang/article/details/47068487

popMenu

popMenu实现在某个view的上方或者下方显示一个折叠的系统风格的折叠菜单,向上还是向下弹出由系统控制(下方有空间从下方弹出,下方没有空间从上方弹出)

//初始化按钮
mPopMenuBtn = (Button) findViewById(R.id.button3);


//为按钮注册点击事件
public void popMenuBtnOnClick(View view) {
//新建一个popMenu实例
        mPopMenu = new PopupMenu(this, mPopMenuBtn);
//为这个实例的menu加载布局资源
        mPopMenu.getMenuInflater().inflate(R.menu.menu_popup_window, mPopMenu.getMenu());
        mPopMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                //do something
                return true;
            }
        });
        mPopMenu.show();
    }

popWindow

模板代码

 private PopupWindow popupWindow;
 @SuppressLint("InflateParams") View     
 view=LayoutInflater.from(this).inflate(R.layout.pop_window_work_reporte,null);
//初始化popWindow
 popupWindow=new 
 PopupWindow(view,ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT,false);
//让popWindow响应点击背景时可以dismiss
 popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
 popupWindow.setOutsideTouchable(true);
//注册popWindow消失监听
 popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
            @Override
            public void onDismiss() {
              //do someThing
            }
        });

与popMenu类似

但是默认实现是点击控件后,在控件下方显示一个窗口,这个窗口可以指定大小以及显示位置,但是不能像popMenu一样自动调整从上方还是下方弹出

另外,popWindow与AlertDialog的区别

最关键的区别是AlertDialog不能指定显示位置,只能默认显示在屏幕最中间(当然也可以通过设置WindowManager参数来改变位置)。而PopupWindow是可以指定显示位置的,随便哪个位置都可以,更加灵活。(引用https://blog.csdn.net/harvic880925/article/details/49272285)

下面简单实现一个popWindow() 实现mPopWindowBtn的下拉菜单效果

//初始化按钮
mPopWindowBtn = (Button) findViewById(R.id.button4);

public void popWindowBtnOnClick(View view) {
//通过布局文件获取一个View
        mPopWindowView = getLayoutInflater().inflate(R.layout.dialog_layout, null);
//新建一个window,为这个window填充视图,指定宽度高度,指定是否可以点击
// Focusable 为True,PopupWindow的点击事件才会相应
        mPopWindow = new PopupWindow(mPopWindowView, WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT, true);
//为窗口中的控件注册点击事件
	TextView choosePhoto = (TextView) mPopWindowView.findViewById(R.id.choosePhoto);
        TextView takePhoto = (TextView) mPopWindowView.findViewById(R.id.takePhoto);
        choosePhoto.setOnClickListener(this);
        takePhoto.setOnClickListener(this);
//控制窗口弹出位置
//showAsDropDown,作为下拉菜单.showAtLocation(),选择弹出位置.
        mPopWindow.showAsDropDown(mPopWindowBtn);
    }

@Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.takePhoto:
                Toast.makeText(this,"点击了拍照",Toast.LENGTH_SHORT).show();
                Log.i(TAG, "onClick: v.getId="+view.getId());
                break;
            case R.id.choosePhoto:
                Toast.makeText(this,"点击了从相册选择",Toast.LENGTH_SHORT).show();
                Log.i(TAG, "onClick: v.getId="+view.getId());
                break;
        }

       //关闭窗口
            mPopWindow.dismiss();
        
    }

如果想要控制window弹出的位置

可以通过showAtLocation()来控制

例如,让窗口在actionbar的右下角弹出

int height=layoutActionbar.getHeight() ;
popWindow.showAtLocation(layoutActionbar, Gravity.END| Gravity.TOP,0,height);

高度和宽度是像素值,控件的高度宽度

获取控件高度宽度 https://blog.csdn.net/CodeIsPoisonous/article/details/54316025

像素转换https://www.cnblogs.com/strinkbug/p/5780910.html

showanlocation的一个小bug

参数,x,y,偏移量为0的时候,没有问题,显示在xml的布局右上角

但是 参考 https://segmentfault.com/q/1010000004319065?sort=created

y增加偏移量的时候,发现距离对不上,上文需要添加50像素

其实我猜测,增加偏移量以后,系统设置的偏移量是根据的手机屏幕的右上角或者左上角为原点,而不是我们定义的xml框架的左上角右上角.手机屏幕的上边会有电源信号的状态栏,增加的这50其实就是状态栏的高度

假设状态栏高度为50,如果我们把y偏移量改为49或者任意小于50的数字,发现与0等同.

获取状态栏高度   https://blog.csdn.net/w_kahn/article/details/50684436

private int getStatusBarHeight(Context context) {
       int result = 0;
       int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
       if (resourceId > 0) {
           result = context.getResources().getDimensionPixelSize(resourceId);
       }
       return result;
}

当状态栏不存在的时候会返回0;

 

窗口中的点击事件需要自己注册,没有类似于popMenu自己的监听器

默认popWindow点击back和外部控件,会先关闭窗口,需要再次点击back和外部控件才能触发相应的点击事件

如果需要popWindow既能响应back和外部控件点击关闭窗口,又能同时触发外部控件的点击事件

可以这样设置

popupWindow.setFocusable(false);

popupWindow.setOutsideTouchable(true);

 

有时候popwindow点击外部区域,不会自动dismiss,需要给window设置背景才有效

popWindowEdit.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));

设置popwindow点击和消失时的背景变暗效果(设置透明度)

private void setBackgroundAlpha(float v) {
        WindowManager.LayoutParams lp=this.getWindow().getAttributes();
        lp.alpha=v;
        getWindow().setAttributes(lp);
    }

弹出时设置,消失时改回

                setBackgroundAlpha(0.7f);
                popWindowEdit.setOnDismissListener(new PopupWindow.OnDismissListener() {
                    @Override
                    public void onDismiss() {
                        setBackgroundAlpha(1.0f);
                    }
                });

 

模板代码

//点击时显示popWindow
 case R.id.cb_selector:
                if (popMenu == null) {
                    initPopMenu();
                }
                popMenu.showAsDropDown(cbSelector);
                break;

//popWindow的初始化
View view=getLayoutInflater().inflate(R.layout.pop_window_review_selector,null,false);
        popMenu =new PopupWindow(view,ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT,false);
//        让popWindow支持点击背景消失
        popMenu.setOutsideTouchable(true);
        popMenu.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        popMenu.setOnDismissListener(new PopupWindow.OnDismissListener() {
            @Override
            public void onDismiss() {
                //popWindow消失时的逻辑
            }
        });
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值