美文网首页
[Android 小记] PopupWindow中放置Spinn

[Android 小记] PopupWindow中放置Spinn

作者: graychen | 来源:发表于2017-11-25 13:28 被阅读0次


    错误原因:android.view.WindowManager$BadTokenException: Unable to add window -- token android.view.ViewRootImpl$W@5ec06ba is not valid; is your activity running?

    Spinner有个可以设置Item弹出的样式的属性:android:spinnerMode="dialog" 如果设置成“dropDown” (默认) 会直接闪退

    “dialog”和“dropDown” 有什么不同的地方?

    查看源码寻找spinnerMode 用到的地方,发现构造方法有个int mode的参数。

    参看构造方法的最终实现

    public Spinner(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes, int mode,Theme popupTheme)

    /** * 

    * @param mode Constant describing how the user will select choices from * the spinner. 

    * @see #MODE_DIALOG 

    * @see #MODE_DROPDOWN 

    */

    mode的默认值是MODE_THEME 即样式为MODE_DIALOG 。

    总结:

        通过对以上源码的分析,发现SpinnerMode有两种dialogDialogPopup,当SpinnerMode为dialog时,Spinner内部选择用一个DialogPopup来显示下拉列表内容;当SpinnerMode为dropDown时,Spinner选择用一个DropdownPopup来显示下拉列表内容

        再次对比DialogPopupDropdownPopup的区别

    发现,DialogPopup用的是dialog去显示item的,DropdownPopup用的是popwindow显示item。所以问题变成为在popwindow中嵌套使用dialog没有问题,而popwindow嵌套使用popwindow就会报错。关于PopupWindow、Dialog窗口添加机制的不同之处推荐阅读Android 窗口添加机制系列2-Dialog,PopupWindow,Toast

    总结如下:

    PopupWindow

    PopupWindow本身依附的WindowToken实际上是也是Activity所依附的WindowToken,这也就是说PopupWindow与Activity所使用的WindowToken是一致的。

    PopupWindow内部不能再使用PopupWindow是因为它获取不到父PopupWindow的WindowToke,从这里我们也可以分析出,一个视图内部不能嵌套与之平级的视图。

    Dialog

    Dialog在初始化视图时,在获取到Activity的WindowToken后,会重新new一个Window,它与Activity分属于不同的Window。

    所以就不会报出WindowManager 获取不到当前activity没有running的问题。

    解决方案有以下方式:

    1.直接将SpinnerMode修改为dialog。但是这样会变成在PopupWinow上弹出一个Dialog,影响美观

    2.将PopupWindow替换为Dialog,dialog上使用PopupWindow
    3.将PopupWindow换为Activity,可能不适用于就是只想弹窗显示

    4.使用自定义组件实现类Spinner效果。比如点击显示一个layout,里面放置textview。

    相关文章

      网友评论

          本文标题:[Android 小记] PopupWindow中放置Spinn

          本文链接:https://www.haomeiwen.com/subject/cahcbxtx.html