无法为TYPE_SYSTEM_OVERLAY获取Touch事件

时间:2013-02-18 14:42:28

标签: android background overlay android-gesture

我喜欢开发一个类似于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,那么我无法获得点击事件。

4 个答案:

答案 0 :(得分:8)

要隐藏视图,您需要调用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);
                    }
                });

            }

答案 1 :(得分:2)

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

答案 2 :(得分:1)

您完成此任务的方法非常不寻常。只需添加一个新视图就可以完成任务。

添加此代码:

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了解更多信息。

答案 3 :(得分:1)

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

并使用下面的代码来获取手势

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;
    }