Android之使用PopupWindow使用和总结

来源:互联网 发布:中国文化深层结构 知乎 编辑:程序博客网 时间:2024/04/29 04:04

不废话,先爆照


说明:

那个灰色背景是不能滑动里ListView里面的内容的

第一步:我们需要背景view

下面是我的background.xml文件
<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="match_parent"    tools:context=".HomeActivity"    >    <RelativeLayout        android:id="@+id/rl_search_background"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:focusable="true"        android:focusableInTouchMode="true"        android:paddingTop="4dp"        android:paddingBottom="4dp"        android:paddingLeft="8dp"        android:paddingRight="8dp">        <RelativeLayout            android:id="@+id/bt_nearby_search_background"            android:layout_width="match_parent"            android:layout_height="30dp"            android:layout_centerInParent="true"            android:background="@drawable/bg_search"            android:padding="4dp"            android:gravity="center">            <Button                android:id="@+id/btn_search_icon_background"                android:layout_width="16dp"                android:layout_height="16dp"                android:layout_centerVertical="true"                android:background="@mipmap/icon_search"                android:clickable="false" />            <EditText                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_toRightOf="@+id/btn_search_icon_background"                android:layout_centerVertical="true"                android:layout_marginLeft="8dp"                android:background="@null"                android:textSize="12sp"                android:hint="@string/search_hint"/>        </RelativeLayout>    </RelativeLayout></RelativeLayout>
design如下

第二步:实现PopupWindow

/**     * 点击评分,如果评分后,显示的弹出框     */    private void makePopupWindows() {        View view = LayoutInflater.from(HomeActivity.this).inflate(                R.layout.background, null);        mPopupWindow = new PopupWindow(view, mScreenWidth, 600);        WindowManager.LayoutParams params = getWindow().getAttributes();        params.alpha = 0.5f;        getWindow().setAttributes(params);        mPopupWindow.setOutsideTouchable(true);        mPopupWindow.setFocusable(true); // 设置PopupWindow可获得焦点        mPopupWindow.setTouchable(true); // 设置PopupWindow可触摸        mPopupWindow.showAsDropDown(background_button);    }

如果你不理解下面三行代码的意思,你可以亲自去测试一下,分别设为true和false,会有什么效果
        mPopupWindow.setOutsideTouchable(true);        mPopupWindow.setFocusable(true); // 设置PopupWindow可获得焦点        mPopupWindow.setTouchable(true); // 设置PopupWindow可触摸

 PopUpWindow的焦点:

setFocusable设置PopupWindow的焦点,一般资料对此的解释都是:是否让Popupwindow可以点击但是这揭示了本质却与直观现象不符。实际上,
如果:
setFocusable(true);
则PopUpWindow本身可以看作一个类似于模态对话框的东西(但有区别),PopupWindow弹出后,所有的触屏和物理按键都有PopupWindows处理。其他任何事件的响应都必须发生在PopupWindow消失之后, (home  等系统层面的事件除外)。比如这样一个PopupWindow出现的时候,按back键首先是让PopupWindow消失,第二次按才是退出activity,准确的说是想退出activity你得首先让PopupWindow消失,因为不并是任何情况下按back  PopupWindow都会消失,必须在PopupWindow设置了背景的情况下 。
如果PopupWindow中有Editor的话,focusable要为true。
而setFocusable(false)
则PopUpWindow只是一个浮现在当前界面上的view而已,不影响当前界面的任何操作
是一个“没有存在感”的东西。
一般情况下setFocusable(true);
点击空白处的时候让PopupWindow消失


关于PopupWindow最搞笑的地方是setOutsideTouchable方法,原本以为如果你setOutsideTouchable(true)则点击PopupWindow之外的地方PopupWindow会消失,其实这玩意儿好像一点用都没有
要让点击PopupWindow之外的地方PopupWindow消失你需要调用setBackgroundDrawable(new BitmapDrawable());
设置背景,为了不影响样式,这个背景是空的。还可以这样写,觉得这样要保险些:
setBackgroundDrawable(new ColorDrawable(0x00000000));
背景不为空但是完全透明。如此设置还能让PopupWindow在点击back的时候消失。其实一直觉得很奇怪,不明白为什么一个背景会影响点击事件,只知道这样用可行。
后来在评论中有人回答了此问题:
如果有背景,则会在contentView外面包一层PopupViewContainer之后作为mPopupView,如果没有背景,则直接用contentView作为mPopupView。
而这个PopupViewContainer是一个内部私有类,它继承了FrameLayout,在其中重写了Key和Touch事件的分发处理

PopupWindow的动画

设置动画的方法:
在res/value/styles.xml添加一个sytle
style name="anim_menu_bottombar">    <item name="android:windowEnterAnimation">@anim/menu_bottombar_in</item>    <item name="android:windowExitAnimation">@anim/menu_bottombar_out</item></style>
在工程res下新建anim文件夹,在anim文件夹先新建两个xml文件
menu_bottombar_in.xml
<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android" >    <translate        android:duration="250"        android:fromYDelta="100.0%"        android:toYDelta="0.0" /></set>
menu_bottombar_out.xml
<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android" >    <translate        android:duration="250"        android:fromYDelta="0.0"        android:toYDelta="100%" /></set>
mPopupWindow.setAnimationStyle(R.style.menu_anim_bottombar);

显示PopupWindow:

showAsDropDown(View anchor):相对某个控件的位置(正左下方),无偏移
showAsDropDown(View anchor, int xoff, int yoff):相对某个控件的位置,有偏移
showAtLocation(View parent, int gravity, int x, int y):相对于父控件的位置(例如正中央Gravity.CENTER,下方Gravity.BOTTOM等),可以设置偏移或无偏移
其实我发现showAtLocation的parent参数可以很随意,只要是activity中的view都可以。

第三步:怎么退出

pw.setFocusable(true),但是当我们这样设置之后,问题出现了,按返回键或者menu菜单键没有反应,怎么退出,请参考我之前的一篇博客
Android之如何解决popupWindow(pw.setFocusable(true))按返回键和menu键退出


最终我的代码如下
/**     * 点击评分,如果评分后,显示的弹出框     */    private void makePopupWindows() {        View view = LayoutInflater.from(HomeActivity.this).inflate(                R.layout.background, null);        mPopupWindow = new PopupWindow(view, mScreenWidth, 600);        WindowManager.LayoutParams params = getWindow().getAttributes();        params.alpha = 0.5f;        getWindow().setAttributes(params);        mPopupWindow.setOutsideTouchable(true);        mPopupWindow.setFocusable(true); // 设置PopupWindow可获得焦点        mPopupWindow.setTouchable(true); // 设置PopupWindow可触摸        mPopupWindow.showAsDropDown(background_button);        view.setFocusableInTouchMode(true);        mPopupWindow.setBackgroundDrawable(new BitmapDrawable());        view.setOnKeyListener(new android.view.View.OnKeyListener() {            public boolean onKey(View v, int keyCode, KeyEvent event) {             // TODO Auto-generated method stub                if (keyCode == KeyEvent.KEYCODE_BACK &&mPopupWindow.isShowing()) {                    mPopupWindow.dismiss();                    WindowManager.LayoutParams params= getWindow().getAttributes();                    params.alpha=1.0f;                    getWindow().setAttributes(params);                    return true;                }                return false;            }        });    }

只要设置监听函数调用这个函数就行




0 0
原创粉丝点击