PopupWindow

本文详细介绍了Android中的PopupWindow与AlertDialog的区别,并展示了PopupWindow的构造方法和显示方式,包括showAsDropDown和showAtLocation。示例代码演示了如何创建、设置属性以及添加动画效果,并提供了屏蔽返回键和空白区域点击关闭PopupWindow的方法。同时,文章还包含了进出场动画的XML定义。
摘要由CSDN通过智能技术生成

1介绍

android的对话框有两种一种是AlertDialog、另一种就是本文要讲的PopupWindow。

与AlertDialog的区别

  1. AlertDialog不能指定显示位置,只能默认显示在屏幕最中间(当然也可以通过设置WindowManager参数来改变位置)。而PopupWindow是可以指定显示位置的,随便哪个位置都可以,更加灵活。

1.1方法

1)构造

public PopupWindow(Context context)
public PopupWindow(View contentView)
public PopupWindow(View contentView, int width, int height)
public PopupWindow(View contentView, int width, int height, boolean focusable)

使用PopupWindow的构造函数必须具有contentView、width、height这三个属性缺一不可。
PopupWindow本身没有布局。所以必须有以上三个属性

如果使用public PopupWindow(Context context)这个构造函数的话当前对象还要添加setContentView、setWidth、setHeight。

View contentView=LayoutInflater.from(MainActivity.this).inflate(R.layout.view_popup, null);
PopupWindow pw= PopupWindow(context);
pw.setContentView(contentView);
pw.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
pw.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);

1.2显示

  1. showAsDropDown(View anchor):(相对某个控件的位置(正左下方),无偏移)
  2. showAsDropDown(View anchor, int xoff, int yoff):(相对某个控件的位置,有偏移;xoff表示x轴的偏移,正值表示向左,负值表示向右;yoff表示相对y轴的偏移,正值是向下,负值是向上;)
  3. showAtLocation(View parent, int gravity, int x, int y):(gravity:相对于父控件的位置(例如正中央Gravity.CENTER,下方Gravity.BOTTOM等),可以设置偏移或无偏移)

2例子

View布局:view_test.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentEnd="true"
            android:orientation="vertical">
		   <TextView
		    android:id="@+id/tv_1"
		    android:layout_width="wrap_content"
		    android:layout_height="wrap_content"
		    android:text="测试1"/>
		   <TextView
		    android:id="@+id/tv_1"
		    android:layout_width="wrap_content"
		    android:layout_height="wrap_content"
		    android:text="测试2"/>
		   <TextView
		    android:id="@+id/tv_1"
		    android:layout_width="wrap_content"
		    android:layout_height="wrap_content"
		    android:text="测试3"/>
    </LinearLayout>
</RelativeLayout>

activity代码:

privite void showPopWindow(View parent){
	View testView= layoutInflater.inflate(R.layout.popupview_renzheng, null);
	PopupWindow popupWindow = new PopupWindow(testView, getWindowManager().getDefaultDisplay().getWidth(),android.view.ViewGroup.LayoutParams.WRAP_CONTENT, true);// 创建一个PopuWidow对象
	//充满屏幕:ViewGroup.LayoutParams.MATCH_PARENT
	popupWindow.setFocusable(true);// 使其聚集
	//mPopupWindow.setBackgroundDrawable(getResources().getDrawable(R.mipmap.ic_launcher));设置背景
	//popupWindow.getBackground().setAlpha(100); //设置透明度
	popupWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);//防止虚拟软键盘呗弹出菜单遮住
	popupWindow.setOutsideTouchable(true);// 设置允许在外点击消失
	popupWindow.setFocusable(true);//是否具有获取焦点的能力
    popupWindow.setTouchable(true);//是否响应touch事件
	popupWindow.setBackgroundDrawable(new BitmapDrawable());// 这个是为了点击“返回Back”也能使其消失,并且并不会影响你的背景
	WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
	popupWindow.showAsDropDown(parent, 0, 0);//parent父控件
	popupWindow.setAnimationStyle(R.style.testStyle);//设置动画所对应的style
	TextView test1=testView.findViewById(R.id.tv_1);
	text1.setOnClickListener(v -> {
		Toast.makeText(this,"测试1",Toast.LENGTH_LONG).show();
		popupWindow.dismiss();//关闭
	});
}

public void shadowMatch(float b) {//阴影
	WindowManager.LayoutParams attributes = getWindow().getAttributes();
	attributes.alpha = b;
	getWindow().setAttributes(attributes);
}

进出场动画style.xml文件中添加:

<style name="testStyle" parent="@android:style/Animation.Activity">
    <item name="android:windowEnterAnimation">@anim/enter_animation</item>
    <item name="android:windowExitAnimation">@anim/exit_animation</item>
</style>

anim下新建以下两个布局

<!--进场动画:enter_animation.xml-->
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:duration="2000">
	<alpha android:fromAlpha="1" android:toAlpha="0"/>
	<translate android:fromXDelta="100%p"
		android:fromYDelta="100%p"
		android:toXDelta="0"
		android:toYDelta="0"/>
</set>

<!--离场动画:exit_animation.xml-->
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:duration="2000">
	<alpha android:fromAlpha="0" android:toAlpha="1"/>
	<translate android:fromXDelta="0"
		android:fromYDelta="0"
		android:toXDelta="100%p"
		android:toYDelta="100%p"/>
</set>

屏蔽返回键与空白键关闭:

//在Android 6.0以上 ,只能通过拦截事件来解决
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
	popupWindow.setTouchInterceptor(new View.OnTouchListener() {
		@Override
		public boolean onTouch(View v, MotionEvent event) {
			final int x = (int) event.getX();
			final int y = (int) event.getY();
			if ((event.getAction() == MotionEvent.ACTION_DOWN)
			&& ((x < 0) || (x >= metrics.widthPixels) || (y < 0) || (y >= metrics.heightPixels))) {
				return true;
			} else if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
				return true;
			}
			return false;
		}
	});
}else{//在Android 6.0以下使用
	popupWindow.setOutsideTouchable(false);
}

数据获取

// 获取屏幕的width和height
iphoneWidth= getWindowManager().getDefaultDisplay().getWidth();
iphoneHeight= getWindowManager().getDefaultDisplay().getHeight();
//获取pop框的宽和高
popWidth = popupWindow.getWidth();
popHeight = popupWindow.getHeight();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值