Android开发之PoupWindow详解

        大家都用过微信的语音,当我们按下按钮的时候开始录音,同时弹出一个显示音量的对话框,如下所示:并且当这个对话框弹出的时候,下面的activity不变暗!一看到这个可能我们第一反应就是自定义布局,使用DialogFragment来实现。但是我们知道默认的AlertDialog或者DialogFragment弹出的时候都会导致其下的Activity失去焦点,变暗,且我一时没找到怎么让屏幕不变暗的方法!


通过在网上找资料,了解到了PoupWindow这个Widget,废话不多说,上代码:

首先是初始化

private DisplayMetrics dm = getResources().getDisplayMetrics();;
	// 弹出框
private PopupWindow exitPoupWindow = null;


private void initExitPoupWindow() {
		//得到布局
		View view = getLayoutInflater().inflate(R.layout.exit_popuwindow, null,
				false);
		//获取按钮控件
		exit = (Button) view.findViewById(R.id.exit_cancel);
		exit.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				initOrDismissExitPoupWindow();
			}
		});
		ok = (Button) view.findViewById(R.id.exit_ok);
		ok.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				initOrDismissExitPoupWindow();
				ActivityCollector.finish_all();
			}
		});
		// 在这里指定PoupWindow大小
		exitPoupWindow = new PopupWindow(view, dm.widthPixels * 2 / 3,
				LayoutParams.WRAP_CONTENT);
		// 使其获得焦点,让外部不可点击,否则外部可点击
		exitPoupWindow.setFocusable(false);
		// 允许接收外部点击事件,这个只有当focusable为false,
		// 且Touchable为真的时候才有意义,外部点击事件将稍后传给这个poupwindow
		// 这个poupwindow就可以对事件进行响应 了
		exitPoupWindow.setOutsideTouchable(true);
		// 允许点击
		exitPoupWindow.setTouchable(true);
		// 设置动画
		exitPoupWindow.setAnimationStyle(R.style.mypopwindow_anim_style);
		// 这里也可以设置activity的透明度!
		WindowManager.LayoutParams params = getWindow().getAttributes();
		params.alpha = 0.5f;
		getWindow().setAttributes(params);
		// 注册监听事件,点击别的地方消失
		view.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				initOrDismissExitPoupWindow();
				return false;
			}
		});
	}

然后写一个方法用于初始化或者销毁PopuWindow
private void initOrDismissExitPoupWindow() {
		if (exitPoupWindow != null && exitPoupWindow.isShowing()) {
			exitPoupWindow.dismiss();
			exitPoupWindow = null;
			// 还原透明效果
			WindowManager.LayoutParams params = getWindow().getAttributes();
			params.alpha = 1f;
			getWindow().setAttributes(params);
		} else {
			initExitPoupWindow();
		}
	}

最后是一个显示的方法
private void showExitPoupWindow(View parent) {
		// 初始化弹出框
		initOrDismissExitPoupWindow();
		// 设置弹出位置:显示到正中间
		exitPoupWindow.showAtLocation(parent, Gravity.CENTER, 0, 0);
		// exitPoupWindow.showAsDropDown(anchor);
		// exitPoupWindow.showAsDropDown(anchor, xoff, yoff);
	}
这个方法得传进一个view参数,相当于poupwindow得绑定到这个view上面,如果是点击一个按钮弹出这个poupwindow的话就直接在onClick或者onTouch中把参数传进去即可!
但是,我在使用得时候遇到了一个问题:我是点击ActionBar的菜单项的时候弹出这个poupwindow,但是不知道怎么获取到这个菜单项的view!于是采用了如下方法,就可以弹出这个poupwindow了!
case R.id.action_exit:
			showExitPoupWindow(MainUI.this.getWindow().getDecorView());
			break;

最终效果如下,当然字体是我系统的字体^_^:

对应的布局文件如下所示,比较简单
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/exit_poupwindow"
    android:gravity="center_horizontal"
    android:orientation="vertical"
    android:paddingLeft="10dp"
    android:paddingRight="10dp"
    android:paddingTop="10dp" >

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="0dp"
        android:gravity="center"
        android:text="提示"
        android:textColor="@color/actionbar_background"
        android:textSize="17sp"
        android:textStyle="bold" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="5dp"
        android:gravity="center"
        android:text="你确定要退出本应用吗?"
        android:textColor="@color/actionbar_background"
        android:textSize="17sp" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="5dp"
        android:orientation="horizontal" >

        <Button
            android:id="@+id/exit_cancel"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="@drawable/exit_button"
            android:text="取消"
            android:textColor="@color/actionbar_background"
            android:textSize="17sp" />

        <Button
            android:id="@+id/exit_ok"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            android:layout_weight="1"
            android:background="@drawable/exit_button"
            android:text="确定"
            android:textColor="@color/actionbar_background"
            android:textSize="17sp" />
    </LinearLayout>

</LinearLayout>

以及动画定义文件popshow_anim.xml,显示弹出动画:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
   <translate
    android:duration="300"
    android:fromYDelta="100%p"
    android:toYDelta="0" />

  <alpha
    android:duration="300"
    android:fromAlpha="0.0"
    android:toAlpha="1.0" />
</set>
pophidden_anim.xml,显示退出动画:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
    android:duration="300"
    android:fromYDelta="0"
    android:toYDelta="50%p" />

  <alpha
    android:duration="300"
    android:fromAlpha="1.0"
    android:toAlpha="0.0" />

</set>

然后styles文件里面定义动画style:
 <style name="mypopwindow_anim_style">
    <item name="android:windowEnterAnimation">@anim/popshow_anim</item>
 <!-- 指定显示的动画xml -->

    <item name="android:windowExitAnimation">@anim/pophidden_anim</item>
 <!-- 指定消失的动画xml -->
  </style>

通过以上步骤我们就可以自定义poupwindow布局,随心所欲的实现我们想要的效果^_^,还可以设置弹出和消失的动画,是不是很nice!

不过有一点需要注意:默认poupwindow弹出的时候是不会使屏幕变暗的,如果想让屏幕变暗就可以设置屏幕的透明度,如下所示,然后在消失的时候再设置透明度为1.0f就恢复了^_^!
// 这里也可以设置activity的透明度!
		WindowManager.LayoutParams params = getWindow().getAttributes();
		params.alpha = 0.5f;
		getWindow().setAttributes(params);


先写这么多!







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值