Android M ClassCastException:FrameLayout$LayoutParams不能强制转换为WindowManager$LayoutParams

Android M ClassCastException:FrameLayout$LayoutParams不能强制转换为WindowManager$LayoutParams,android,android-6.0-marshmallow,layoutparams,android-popupwindow,Android,Android 6.0 Marshmallow,Layoutparams,Android Popupwindow,这段代码在AndroidAPI16-22中似乎有效,但在API23中不起作用。我只是想显示一个带有选项的弹出窗口,并将弹出窗口下方的背景调暗: WindowPopUp windowPopUp = new WindowPopUp(mContext, mPlaces.get(position), position, fromSearch); windowPopUp.showAtLocati

这段代码在AndroidAPI16-22中似乎有效,但在API23中不起作用。我只是想显示一个带有选项的弹出窗口,并将弹出窗口下方的背景调暗:

                WindowPopUp windowPopUp =
                        new WindowPopUp(mContext, mPlaces.get(position), position, fromSearch);
                windowPopUp.showAtLocation(v, Gravity.CENTER, 0, 0);
                View parent = (View) windowPopUp.getContentView().getParent();
                //dim the window in the background
                WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
                WindowManager.LayoutParams p = (WindowManager.LayoutParams) parent.getLayoutParams();
                p.flags = WindowManager.LayoutParams.FLAG_DIM_BEHIND;
                p.dimAmount = 0.4f;
                wm.updateViewLayout(parent, p);
运行此代码会导致错误:

                03-18 21:55:19.674 8814-8814/? E/AndroidRuntime: FATAL EXCEPTION: main
                                             Process: com.myapp, PID: 8814
                                             java.lang.ClassCastException: android.widget.FrameLayout$LayoutParams cannot be cast to android.view.WindowManager$LayoutParams
                                                 at com.bemyapp.adapter.OuterPlaceAdapter$5.onLongClick(OuterPlaceAdapter.java:400)
                                                 at android.view.View.performLongClick(View.java:5237)
                                                 at android.view.View$CheckForLongPress.run(View.java:21121)
                                                 at android.os.Handler.handleCallback(Handler.java:739)
                                                 at android.os.Handler.dispatchMessage(Handler.java:95)
                                                 at android.os.Looper.loop(Looper.java:148)
                                                 at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                 at java.lang.reflect.Method.invoke(Native Method)
                                                 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
出了什么问题


据我所知,
WindowManager.LayoutParams
扩展了
ViewGroup.LayoutParams
,当我调用
parent.getLayoutParams()
时,它返回一个
ViewGroup.LayoutParams
,因此不应该存在
classCastException
类强制转换异常。您正在将
ViewGroup.LayoutParams
强制转换为
WindowManager.LayoutParams
。如果返回的实际对象是
ViewGroup.LayoutParams
(例如,
FrameLayout.LayoutParams
)的不同子对象的实例,则强制转换是非法的。在这种情况下,名为parent的视图不直接在窗口中,而是在
框架布局中。因此,调用
getLayoutParams
将返回一个
FrameLayout.LayoutParams
,而不是
WindowsManager.LayoutParams


如果它在22而不是23中工作,那么很有可能它们在23中改变了弹出窗口的工作方式。依赖父弹出窗口直接位于窗口内部从来都不是一个安全的假设,您的代码总是有被操作系统更新破坏的风险。

只需再添加一个.getParent()即可访问容器

 if (android.os.Build.VERSION.SDK_INT > 22) {
            container = (View) pwindow.getContentView().getParent().getParent();
        }else{
            container = (View) pwindow.getContentView().getParent();
        }

添加了一个编辑。基本上,您依赖于他们更改的实现细节。这是个可怕的消息。我想我得把我所有的弹出窗口都改成DialogActivity。如果这是真的,PopupWindow不是一个好的设计想法。也许不是针对您的用例,尽管它是针对其他用例的。您也可以通过在视图层次结构中向上走直到碰到一个窗口(他们可能刚刚添加了一个框架来处理单个窗口中的多个弹出窗口)来获得所需的内容。但他们可能只是改变了它,使主窗口和弹出窗口都在一个框架中,在这种情况下,这将不起作用。你想出解决办法了吗?