PopupWindow弹出窗口的使用
正文
PopupWindow pw=new PopupWindow(view,LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
pw.showAsDropDown(anchor, xoff, yoff);//相对某个控件的下方,有偏移量的设置
//相对于整个窗口的。并不是相对于parent这个View来确定位置的
第一个参数是View类型的parent,虽然这里参数名是parent,其实,不是把PopupWindow放到这个parent里,并不要求这个parent是一个ViewGroup,这个参数名让人误解。这个parent的作用应该是调用其getWindowToken()方法获取窗口的Token,所以,只要是该窗口上的控件就可以了。
pw.showAtLocation(parent, gravity, x, y);
pw.dismiss();//关闭弹窗
pw.setBackgroundDrawable(getResources().getDrawable(R.id.));//设置背景图片
pw.getBackground().setAlpha(100);//背景透明度
pw.setAnimationStyle();//设置动画效果 可以使用系统自带的popupWindow.setAnimationStyle(android.R.style.Animation_Translucent);进入的动画
pw.setOutsideTouchable(true);//设置点击窗口外边窗口消失 ,注意设置背景色后该方法才有效
pw.setFocusable(true);//获取焦点,可以防止窗体里的控件不能滑动,或者不能展开之类的问题,当点击外部消失的时候也可以仿真执行外部的触摸事件
pw.setTouchable(true);//可以触摸
//防止虚拟键盘弹出时被该窗口遮住
pw.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
pw.setClippingEnabled(false); // 允许弹出窗口超出屏幕范围。默认情况下,窗口被夹到屏幕边界。设置为false将允许Windows精确定位。
//实例化ColorDrawable为半透明
ColorDrawable dw=new ColorDrawable(0x80000000);
window.setBackgroudDrawable(dw);
使用见:自定义下拉列表与PopupWindow的使用(弹出窗口)
显示在指定控件的上方:
View inflate = LayoutInflater.from(this).inflate(R.layout.near_about_ta_layout, null); popupWindow = new PopupWindow(inflate, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); ColorDrawable dw = new ColorDrawable(0x10ab82ff); popupWindow.setBackgroundDrawable(dw); popupWindow.setOutsideTouchable(true); // 获取窗体显示的布局的长宽高,然后设置偏移量就能显示在指定控件的上方了 测量出布局的宽高 inflate.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); popupWindow.showAsDropDown(tv_about_ta, 0, (int) -(inflate.getMeasuredHeight() + tv_about_ta.getHeight()));
弹窗后让窗体其他区域变暗:
/** * 显示点击推广后的窗体 */ private void showPopularizeWindow() { dismissPopupWindow();// 显示销毁已经显示在屏幕上的 View inflate = LayoutInflater.from(this).inflate(R.layout.near_popularize_layout, null); popupWindow = new PopupWindow(inflate, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); //弹窗后,让窗体其他区域变暗(类似于对话框) WindowManager.LayoutParams params=getWindow().getAttributes(); params.alpha=0.4f; getWindow().setAttributes(params); ColorDrawable dw = new ColorDrawable(0x10ab82ff); popupWindow.setBackgroundDrawable(dw); popupWindow.setOutsideTouchable(true); // 获取自身的长宽高 inflate.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); popupWindow.showAsDropDown(tv_popularize, 0, (int) -(inflate.getMeasuredHeight() + tv_popularize.getHeight())); //在窗体销毁后,让当前界面的颜色变回来,不然还是会保存变暗 popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() { @Override public void onDismiss() { WindowManager.LayoutParams params=getWindow().getAttributes(); params.alpha=1f; getWindow().setAttributes(params); } }); }
效果图: 真机上不会出现上面没有变暗的现象
如果想为窗体设置动画:
<!--为窗体设置动画:popupWindow.setAnimationStyle(R.style.PopupAnimation);--> <style name="PopupAnimation" parent="android:Animation"> <!--窗体显示的动画--> <item name="android:windowEnterAnimation">@anim/popup_enter</item> <!--窗体退出时的动画--> <item name="android:windowExitAnimation">@anim/popup_exit</item> </style>
例2: 弹出窗口PopupWindow的简单例子: 下面为主要代码,在悬浮窗体里显示一个TextView. 也可以显示布局文件的
private PopupWindow window;//悬浮窗体 //ListView单击事件 listView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { TextView tv=new TextView(MainActivity.this); tv.setText("悬浮文本");//PopuPWindow的显示内容 tv.setTextColor(Color.RED); dismissPopupWindow();//显示销毁已经显示在屏幕上的 window = new PopupWindow(tv, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); //为popupWindow设置背景颜色 window.setBackgroundDrawable(new ColorDrawable(Color.GRAY));//TRANSPARENT代表透明,一般也设置为透明色 int[] location=new int[2]; //会把view的坐标赋值到location数组中,这里view就为listView的item的布局 view.getLocationInWindow(location); //参数说明:1.显示在parent上(这里parent代表listView),2.左上角,3.偏移量 window.showAtLocation(parent, Gravity.LEFT | Gravity.TOP, location[0], location[1]); //为窗体中显示的布局控件设置动画,注意前提是必须为窗体设置了背景色,动画才有效果,透明色也可以 ScaleAnimation sa=new ScaleAnimation(0.3f,1.0f,0.3f,1.0f, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f); sa.setDuration(2000); AlphaAnimation aa=new AlphaAnimation(0f,1f); aa.setDuration(2000); AnimationSet set=new AnimationSet(false); set.addAnimation(aa); set.addAnimation(sa); tv.startAnimation(set);//执行动画 }
}); /** * 把旧的popupWindow消灭掉,避免在屏幕上显示多个popupWindow */ private void dismissPopupWindow(){ //如果wivdow不为空,且已经在显示,就销毁掉,避免显示多个窗体 if(window!=null && window.isShowing()){ window.dismiss(); window=null; }
} @Override protected void onDestroy() { super.onDestroy(); dismissPopupWindow();//当前活动销毁了需要将窗体手动销毁掉,不然出现异常(窗体泄露) }
效果: 这里为没有增加 dismissPopupWindow()方法时的效果,增加后就避免了显示多个窗体,注意这里没有加listView的滑动监听,
如果不在滑动监听里面销毁掉PopupWindow的显示,当滑动listView时,已经显示了的popupWindow不会跟着滑动,而是保持屏幕的原位置.
上图显示的控件X坐标值为0,所以如果想让该窗体靠右显示,就需要这样设置:(由于在代码中设置的宽高系统会认为是像素值,这样使得在不同屏幕大小的手机上显示的位置有偏差,所以需要转化为dp单位的值,这样不管在多大屏幕的手机上,所展现出来的位置是一样的)
//实际单位为像素px 改为这样,也就是60dp了 window.showAtLocation(parent, Gravity.LEFT | Gravity.TOP, location[0]+dip2px( getApplicationContext(),60f ), location[1]);
单位转化如下:
/** * 在java代码中设置的宽高都以像素px为单位 * 根据手机的分辨率从 dip 的单位 转成为 px(像素) */ public static int dip2px(Context context, float dpValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); }
封装得比较好的第三方库: EasyPopup 使用如下:
paramterDialog = new EasyPopup(getActivity()) .setContentView(R.layout.dialog_bottom_product_paramter, ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT) .setAnimationStyle(R.style.below_top_PopupAnimation) .setFocusAndOutsideEnable(true)//是否允许点击PopupWindow之外的地方消失 //允许背景变暗 .setBackgroundDimEnable(true) .setDimValue(0.4f)//变暗的透明度(0-1),0为完全透明 //.setDimColor(Color.YELLOW)//变暗的背景颜色,默认灰色透明 //.setDimView(ivBannerGoods)//指定任意 ViewGroup 背景变暗, 默认为activity .createPopup(); //找控件 paramterDialog.getContentView().findViewById(R.id.rv_paramter); //显示 paramterDialog.showAtLocation(getView(), Gravity.BOTTOM,0,0);
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步