大家都用过微信的语音,当我们按下按钮的时候开始录音,同时弹出一个显示音量的对话框,如下所示:并且当这个对话框弹出的时候,下面的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);
先写这么多!