【问题标题】:Could not get Touch event for TYPE_SYSTEM_OVERLAY无法获取 TYPE_SYSTEM_OVERLAY 的触摸事件
【发布时间】:2017-01-19 23:25:26
【问题描述】:

我喜欢开发一个类似于Swapps 的应用程序。我试图在任何屏幕上显示一个按钮,并且应该只在滑动操作时发生。我尝试使用以下代码

    WindowManager.LayoutParams params = new WindowManager.LayoutParams();
    params.type =WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
    params.flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
    params.format =PixelFormat.TRANSLUCENT; 
    params.height = WindowManager.LayoutParams.WRAP_CONTENT;
    params.width = WindowManager.LayoutParams.WRAP_CONTENT;
    parentlay = new LinearLayout(this);
    mybt = new Button(getApplicationContext());
    bt.setText("Click to Go");

    parentlay.setBackgroundColor(Color.TRANSPARENT);
    parentlay.setHapticFeedbackEnabled(true);
    parentlay.setOnTouchListener(new OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
                // event.getAction() prints 4 and not able to get up or down event
           }
       });
   windowmanager.addView(parentlay, params);

当用户通过捕获该事件并执行从左到右滑动时,我试图显示按钮

    parentlay.addView(bt);

当用户从右向左滑动时移除视图

    parentlay.removeView(bt);

如前所述,除非我将类型更改为 TYPE_SYSTEM_ALERT ,否则我无法获取运动事件,但这反过来会冻结所有屏幕并且无法单击返回或主页按钮,是否有其他方法可以做到这一点。

我刚刚尝试了下面的修改

    params.type =WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
    params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
    |WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
   |WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;

    params.height = WindowManager.LayoutParams.MATCH_PARENT;
    params.width = WindowManager.LayoutParams.MATCH_PARENT;

但我无法点击下方的按钮,可能是由于 MATCH_PARTENT 但如果我将其设置为 wrap_content 则我无法获得点击事件。

【问题讨论】:

    标签: android background overlay android-gesture


    【解决方案1】:

    要隐藏视图,您需要调用 mWindowManager.removeView(mOverlay);

    private RelativeLayout mOverlay;
            private WindowManager mWindowManager;   
         WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                            WindowManager.LayoutParams.WRAP_CONTENT,
                            WindowManager.LayoutParams.WRAP_CONTENT,
                            WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
                            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                                    | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
                            PixelFormat.TRANSLUCENT);
                    params.gravity = Gravity.TOP;
                    LayoutInflater inflater = (LayoutInflater) context
                            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                    mOverlay = (RelativeLayout) inflater
                            .inflate(R.layout.phasechange, null);
    
                    mWindowManager = (WindowManager) context
                            .getSystemService(Context.WINDOW_SERVICE);
                    mWindowManager.addView(mOverlay, params);
                    Button b = (Button) mOverlay.findViewById(R.id.button1);
                    b.setOnClickListener(new OnClickListener() {
    
                        @Override
                        public void onClick(View v) {
                            // TODO Auto-generated method stub
                            mWindowManager.removeView(mOverlay);
                        }
                    });
    
                }
    

    【讨论】:

    • 感谢您的回复,我需要通过滑动动作或任何动作事件添加视图,就像 swapps 所做的那样。我没有启动我的应用程序。并通过动作事件删除视图
    • 好的,现在我可以接受 DjHacktor 的回答,因此它非常接近我的要求
    【解决方案2】:

    使用窗口类型TYPE_PHONE 代替TYPE_SYSTEM_OVERLAY,以及标志FLAG_NOT_FOCUSABLE

    【讨论】:

      【解决方案3】:

      从准则中查看总是很忙,而且有点难以管理。因此,您也可以在布局中添加按钮,并根据您的滑动使其可见和不可见。

      并使用以下代码获取手势

      public class MyGestureDetector implements OnGestureListener {
              @Override
              public boolean onDown(MotionEvent arg0) {
                  return false;
              }
      
              @Override
              public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                      float arg3) {
                  return setCurrentSwipeTab(e1, e2, velocityX, arg3);
              }
      
              @Override
              public void onLongPress(MotionEvent arg0) {
              }
      
              @Override
              public boolean onScroll(MotionEvent arg0, MotionEvent arg1, float arg2,
                      float arg3) {
                  return false;
              }
      
              @Override
              public void onShowPress(MotionEvent e) {
              }
      
              @Override
              public boolean onSingleTapUp(MotionEvent e) {
                  return false;
              }
          }
      
      
      public boolean setCurrentSwipeTab(MotionEvent e1, MotionEvent e2,
                  float velocityX, float arg3) {
              try {
                  if (Math.abs(e1.getY() - e2.getY()) > Util.SWIPE_MAX_OFF_PATH)
                      return false;
                  // Left to right swipe of the user detected
                  if (e1.getX() - e2.getX() > Util.SWIPE_MIN_DISTANCE
                          && Math.abs(velocityX) > Util.SWIPE_THRESHOLD_VELOCITY) {
      
                      }
                          // Nothing to do since you are at the Last tab!! it's task
                          // of the left swipe now
                      }
                  } else if (e2.getX() - e1.getX() > Util.SWIPE_MIN_DISTANCE
                          && Math.abs(velocityX) > Util.SWIPE_THRESHOLD_VELOCITY) {
      
              } catch (Exception e) {
                  e.printStackTrace();
              }
              return false;
          }
      

      【讨论】:

        【解决方案4】:

        您完成这项任务的方法非常不同寻常。只需添加一个新视图就可以很好地完成任务。

        添加此代码:

        RelativeLayout layout = new RelativeLayout(this);
        Button b = new Button(this);
        b.setBackgroundColor(Color.LTGRAY);
        b.setText("Click to Go");
        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
        params.addRule(RelativeLayout.CENTER_IN_PARENT);
        b.setLayoutParams(params);
        layout.addView(b);
        
        //get a reference to your main layout:
        ViewGroup myLayout = findViewById(R.id.whateverMayLayoutIdIs);
        layout.addView(layout);
        

        要隐藏视图,您可以将其从布局中移除,或更改其可见性。

        您使用的方法非常棘手,并且其他人在处理触摸时遇到了问题。示例包括 Android : Multi touch and TYPE_SYSTEM_OVERLAYGestureDetector within a TYPE_SYSTEM_OVERLAY。尝试this google search 了解更多信息。

        【讨论】:

          猜你喜欢
          • 2012-07-07
          • 2011-07-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-01-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多