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常用的构造方法:

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

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

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

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

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


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方向上有偏移  
        PopupWindow显示在控件的左下方,x和y方向上有偏移
     (和上面的方法一样,虽然多了一个参数,但貌似官方文档上对其描述都一样)

        指定相对于父控件的位置(Gravity.LEFT | Gravity.TOP.……),可以指定偏移,其实所谓的父控件,

      随意指定啦

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

先看一下最常见的一种 


效果图:
   

主要代码:

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代码:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_horizontal"
    android:orientation="vertical" >

    <LinearLayout
        android:id="@+id/pop_layout2"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:alpha="0.8"
        android:background="@drawable/popover_background"
        android:gravity="center_horizontal"
        android:orientation="vertical" >

        <LinearLayout
            android:id="@+id/lin_car_empty"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:orientation="horizontal"
            android:padding="8dp" >

            <TextView
                android:id="@+id/tv_car_empty"
                android:layout_width="wrap_content"
                android:layout_height="fill_parent"
                android:layout_marginLeft="10dp"
                android:gravity="center"
                android:text="空车"
                android:textColor="#FFFFFF"
                android:textSize="18sp" />
        </LinearLayout>

        <View
            android:layout_width="fill_parent"
            android:layout_height="0.1dp"
            android:layout_marginLeft="0dp"
            android:layout_marginRight="0dp"
            android:background="@drawable/divider_horizontal_line" />

        <LinearLayout
            android:id="@+id/lin_car_half"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:orientation="horizontal"
            android:padding="8dp" >

            <TextView
                android:id="@+id/tv_car_half"
                android:layout_width="wrap_content"
                android:layout_height="fill_parent"
                android:layout_marginLeft="10dp"
                android:gravity="center"
                android:text="半载"
                android:textColor="#FFFFFF"
                android:textSize="18sp" />
        </LinearLayout>

        <View
            android:layout_width="fill_parent"
            android:layout_height="0.1dp"
            android:layout_marginLeft="0dp"
            android:layout_marginRight="0dp"
            android:background="@drawable/divider_horizontal_line" />

        <LinearLayout
            android:id="@+id/lin_car_full"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:orientation="horizontal"
            android:padding="8dp" >

            <TextView
                android:id="@+id/tv_car_full"
                android:layout_width="wrap_content"
                android:layout_height="fill_parent"
                android:layout_marginLeft="10dp"
                android:gravity="center"
                android:text="满载"
                android:textColor="#FFFFFF"
                android:textSize="18sp" />
        </LinearLayout>

        <View
            android:layout_width="fill_parent"
            android:layout_height="0.1dp"
            android:layout_marginLeft="0dp"
            android:layout_marginRight="0dp"
            android:background="@drawable/divider_horizontal_line" />

        <LinearLayout
            android:id="@+id/lin_car_rest"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:orientation="horizontal"
            android:padding="8dp" >

            <TextView
                android:id="@+id/tv_car_rest"
                android:layout_width="wrap_content"
                android:layout_height="fill_parent"
                android:layout_marginLeft="10dp"
                android:gravity="center"
                android:text="勿扰"
                android:textColor="#FFFFFF"
                android:textSize="18sp" />
        </LinearLayout>
    </LinearLayout>

</RelativeLayout>
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 正左下方
则会显示在正左下方:


还有的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,设置的动画效果为从底部弹出。

效果图:



还有的情况是点击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的上面或者下面,或者任意位置。

效果图:
  


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


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

好了,下面来看Demo实现

猜你喜欢

转载自blog.csdn.net/yalinfendou/article/details/45966641
今日推荐