Android PopupWindow使用详解

       先来看一下PopupWindow的描述:

       A popup window that can be used to display an arbitrary view. The popup window is a floating container that appears on top of the current activity.

       PopupWindow 是弹出窗口,可以用来显示任意一个视图。出现的弹出窗口是一个在当前Activity之上的浮动容器。

       PopupWindow常用的构造方法:

  • PopupWindow(Context context)

Create a new empty, non focusable popup window of dimension (0,0).参数为上下文,创建一个高宽为0 的没有焦点的PopupWindow

  • PopupWindow()

Create a new empty, non focusable popup window of dimension (0,0).无参,创建一个高宽为0 的没有焦点的PopupWindow

  • PopupWindow(View contentView)

Create a new non focusable popup window which can display the contentView.参数为要显示的View,即PopupWindow要显示的视图

  • PopupWindow(int width, int height)

Create a new empty, non focusable popup window.参数为要显示的View的宽度和高度

  • PopupWindow(View contentView, int width, int height)

Create a new non focusable popup window which can display the contentView.参数为要显示的View,宽度和高度 


PopupWindow常见方法:

  • dismiss()使PopupWindow消失
  • getWidth()得到PopupWindow宽度
  • getHeight()得到PopupWindow高度
  • isOutsideTouchable()设置popupwindow外部可点击    
  • setAnimationStyle(int animationStyle)PopupWindow设置动画效果
  • setContentView(View contentView)如果不在构造方法中指定要显示的View,则可以使用此方法
  • setHeight(int height)设置PopupWindow高度,如果当前的PopupWindow正显示,那么下次显示时才会有效
  • setWidth(int width)设置PopupWindow宽度,如果当前的PopupWindow正显示,那么下次显示时才会有效
  • showAsDropDown(View anchor)指定PopupWindow显示在控件的左下方
  • showAsDropDown(View anchor, int xoff, int yoff)
       指定PopupWindow显示在控件的左下方,x和y方向上有偏移  
  • showAsDropDown(View anchor, int xoff, int yoff, int gravity)
        PopupWindow显示在控件的左下方,x和y方向上有偏移
     (和上面的方法一样,虽然多了一个参数,但貌似官方文档上对其描述都一样)

  • showAtLocation(View parent, int gravity, int x, int y)  
        指定相对于父控件的位置(Gravity.LEFT | Gravity.TOP.……),可以指定偏移,其实所谓的父控件,

      随意指定啦

  • setBackgroundDrawable(Drawable background)设置PopupWindow背景,可为NULL
其实PopupWindow的基本设置都大同小异,关键还在于要显示的contentView和其显示的位置,contentView中你可以随意布局,
添加各种效果,满足项目 需要。
注意:popupwindow中包含Spinner时,点击Spinner的时候会报错,在spinner的xml中添加一个属性:
android:spinnerMode="dialog"即可(公司项目也曾遇到类似情况)

先看一下最常见的一种 


效果图:
Android PopupWindow使用详解_第1张图片   Android PopupWindow使用详解_第2张图片

主要代码:

private void setMyPop(){
	mPopTop = new PopupWindow(context);
	int w = ScreenUtils.getScreenWidth(context);
	int h = ScreenUtils.getScreenHeight(context);
	mPopTop.setWidth(w / 2);
	mPopTop.setHeight(LayoutParams.WRAP_CONTENT);
	mPopTop.setFocusable(true);////获取焦点    
	mPopTop.setTouchable(true);
	mPopTop.setOutsideTouchable(true);//设置popupwindow外部可点击    
  //	mPopTop.update();// 刷新状态	
	ColorDrawable dw = new ColorDrawable(0000000000);// 实例化一个ColorDrawable颜色为半透明	
	mPopTop.setBackgroundDrawable(dw);// 点back键和其他地方使其消失,设置了这个才能触发OnDismisslistener ,设置其他控件变化等操作
	mPopTop.setAnimationStyle(R.style.AnimationPreview);//设置显示和消失动画
	LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);		
	View conentView = inflater.inflate(R.layout.pop_top, null);
	setContentViewClickListener(conentView);
	mPopTop.setContentView(conentView);
	
}

在上面的代码中对PopupWindow进行了一些常用设置,包括主要的高度宽度设置,要显示的View以及动画效果等等。

conentView的XML代码:




    

        

            
        

        

        

            
        

        

        

            
        

        

        

            
        
    

setContentViewClickListener(conentView)是为要显示的View设置点击事件(在这里添加业务逻辑),我这里只是简单的Toast。
private void setContentViewClickListener(View conentView){
	LinearLayout lin_car_full = (LinearLayout) conentView
			.findViewById(R.id.lin_car_full);
	LinearLayout lin_car_empty = (LinearLayout) conentView
			.findViewById(R.id.lin_car_empty);

	LinearLayout lin_car_half = (LinearLayout) conentView
			.findViewById(R.id.lin_car_half);
	LinearLayout lin_car_rest = (LinearLayout) conentView
			.findViewById(R.id.lin_car_rest);
	lin_car_empty.setOnClickListener(new OnClickListener() {

		@Override
		public void onClick(View arg0) {
			
			  
			   T.showLong(context, "空车");
			   mPopTop.dismiss();
		}
	});

	lin_car_full.setOnClickListener(new OnClickListener() {

		@Override
		public void onClick(View v) {
			
          
           T.showLong(context, "满载");
           mPopTop.dismiss();
		}
	});

	lin_car_half.setOnClickListener(new OnClickListener() {

		@Override
		public void onClick(View arg0) {
		
			 
			   T.showLong(context, "半载");
			   mPopTop.dismiss();
		}
	});

	lin_car_rest.setOnClickListener(new OnClickListener() {

		@Override
		public void onClick(View v) {
			
			 
			   T.showLong(context,"勿扰");
			   mPopTop.dismiss();
		}
	});
}
然后调用,使其显示出来。
mPopTop.showAsDropDown(rel_titlebar, ScreenUtils.getScreenWidth(context)/4, 0); //titleBar 正下方中间位置
或者
 mPopTop.showAtLocation(rel_titlebar, Gravity.TOP, 0, height +ScreenUtils.getStatusHeight(context)); //titleBar 正下方中间位置

说明:
ScreenUtils.getStatusHeight(context)为状态栏的高度
rel_titlebar即titleBar
height为titleBar的高度,
关于测量控件的高度宽度,下面是具体代码
//测量titleBar高度
		ViewTreeObserver vto = rel_titlebar.getViewTreeObserver();
		vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
			public boolean onPreDraw() {
				if (hasMeasured == false) {

					height = rel_titlebar.getMeasuredHeight();
				//	int width = rel_titlebar.getMeasuredWidth();
					// 获取到宽度和高度后,可用于计算

					hasMeasured = true;

				}
				return true;
			}
		});
如果调用
 mPopTop.showAsDropDown(rel_titlebar);//titleBar 正左下方
则会显示在正左下方:
Android PopupWindow使用详解_第3张图片


还有的PopupWindow是全屏显示的


private void showFullPop() {

		View view = LayoutInflater.from(this).inflate(R.layout.pop_full,
				null);
		LinearLayout layout_all;
		RelativeLayout layout_choose;
		RelativeLayout layout_photo;
		RelativeLayout layout_cancel;
		layout_choose = (RelativeLayout) view.findViewById(R.id.layout_choose);
		layout_photo = (RelativeLayout) view.findViewById(R.id.layout_photo);
		layout_cancel=(RelativeLayout) view.findViewById(R.id.layout_cancel);
		layout_photo.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				
				   T.showLong(context,"点击拍照");
				   mPopBottom.dismiss();
				
			}
		});
		layout_choose.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {
			
				 T.showLong(context,"点击相册");
				 mPopBottom.dismiss();
			}
		});
		
		
		layout_cancel.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				
				 T.showLong(context,"点击取消");
				mPopBottom.dismiss();
			
			}
		});

		mPopBottom = new PopupWindow(view);
//		mPopBottom.setTouchInterceptor(new OnTouchListener() {
//			@Override
//			public boolean onTouch(View v, MotionEvent event) {
//				if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
//					mPopBottom.dismiss();
//					return true;
//				}
//				return false;
//			}
//		});

		mPopBottom.setWidth(WindowManager.LayoutParams.MATCH_PARENT);
		mPopBottom.setHeight(WindowManager.LayoutParams.MATCH_PARENT);
		mPopBottom.setTouchable(true);
		mPopBottom.setFocusable(true);
		mPopBottom.setOutsideTouchable(true);
		ColorDrawable dw = new ColorDrawable(0000000000);
		mPopBottom.setBackgroundDrawable(dw);
		// 动画效果 从底部弹起
		mPopBottom.setAnimationStyle(R.style.Animations_GrowFromBottom);

		mPopBottom.showAtLocation(rel_titlebar, Gravity.BOTTOM, 0, 0);//parent view随意

	}

注意这里我们设置View的高度和宽度都为MATCH_PARENT,设置的动画效果为从底部弹出。

效果图:

Android PopupWindow使用详解_第4张图片


还有的情况是点击ListView的Item时弹出PopupWindow(类似QQ消息选项长按出现的效果,PopupWindow随Item的位置不同而变化),要实现此效果,只需指定PopupWindow的显示位置即可。


在布局中添加一个ListView,然后给ListView设置点击事件:

 lv.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView parent, View view,
					int position, long id) {
				
				int[] location = new int[2];
				 view.getLocationOnScreen(location);
				
				 mPopTop.showAtLocation(view, Gravity.NO_GRAVITY, ScreenUtils.getScreenWidth(context) / 4, location[1]);
				// mPopTop.showAtLocation(view, Gravity.NO_GRAVITY,ScreenUtils.getScreenWidth(context) / 4, location[1]);
							
			}
		});

说明:

通过view.getLocationInWindow(location); 获取控件在屏幕内的绝对坐标,location[0]为X坐标值,location[1]为Y坐标值。

这里只是为了演示,没有设置新的PopupWindow,关于PopupWindow的位置,你可以根据项目的实际情况,指定其显示在Item的上面或者下面,或者任意位置。

效果图:
Android PopupWindow使用详解_第5张图片  Android PopupWindow使用详解_第6张图片


另外,如果你想在PopupWindow中显示gridView之类更复杂的View,只需在XML中布局或者在Java代码中动态布局就可以了。


DEMO 下载地址 http://download.csdn.net/detail/yalinfendou/8737193

好了,下面来看Demo实现

你可能感兴趣的:(Android基础知识及总结)