Android Toasts在某些手机上可以获取触摸事件,而在其他手机上则无法获取。

7
我正在使用一个自定义视图的Toast,我实例化了该视图并在Toast上调用了setView方法。这个Toast应该浮在顶部而不接收焦点和触摸事件,并且它能正常工作。但是在启动应用后,用户抱怨说在某些手机型号(如Galaxy Note)上,Toast会收到触摸事件,下面的应用程序却没有反应。
我在setLayoutParams方法中打印了布局参数标志(WindowManager.LayoutParams),结果发现,在大多数设备上,值为0x000098,但在一些设备上为0x040088。在那些Toast接收触摸事件的设备上,标志FLAG_NOT_TOUCHABLE被移除,标志FLAG_WATCH_OUTSIDE_TOUCH被添加。这解释了为什么Toast可以接收触摸事件。
但是是什么原因导致了这种差异?有没有一种方法来强制Toast不可触摸?

你找到答案了吗?另外,你是如何读取Toast参数的? - theJosh
“toast.getView().setEnabled(false);” 对你有效吗?这应该会禁用 Toast 视图上的触摸事件。 - domi
这个问题已经两年了,突然又活跃起来。我现在没有设备可以测试它。 - yoah
@domi 我尝试了toast.getView()。setEnabled(false),但它没有起作用。虽然听起来不错。 - theJosh
@theJosh 我没有找到答案。我使用了SYSTEM_ALERT_WINDOW,可以在其中明确设置标志。 - yoah
1个回答

1
我有一个解决方法。您需要访问Toast所覆盖的视图。您可以捕获传递给Toast的触摸事件。然后更改MotionEvent X和Y。然后将MotionEvent发送到被遮挡的视图。这对我来说感觉有点hacky,但它确实有效。我认为更好的方法是更改Toast上的标志,但我找不到它们。
在创建Toast的活动中:
final Taost toast = Toast.makeText(this, "Text", Toast.LENGTH_LONG);
final View myCoveredView = findViewById(R.id.my_covered_view);
final View toastView = toast.getView();

toastView.setOnTouchListener(new OnTouchListener() {

                @Override
                public boolean onTouch(final View v2, final MotionEvent event) {
                    //Make sure the view is accessible
                    if(myCoveredView != null){
                        //Set the touch location to the absolute screen location
                        event.setLocation(event.getRawX(), event.getRawY());
                        //Send the touch event to the view
                        return myCoveredView.onTouchEvent(event);
                    } 
                    return false;
                }
            });

如果有更好的方法,我很乐意听取建议。

对于我的情况来说,这并不好,因为下面的视图属于另一个应用程序。您可以尝试获取Toast的视图,找到窗口并更改窗口标志。我不确定这些标志是否可以更改。 - yoah
Google在Gmail中使用自定义视图来替代普通的提示框,以添加“撤消”按钮。查看这个Stack Overflow问题以获取更多信息。 - sonictt1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接