无法获取 TYPE_SYSTEM_OVERLAY 的触摸事件

10

我想开发一个类似于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_PARENT,但如果将其设置为wrap_content,则无法获得点击事件。

4个回答

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

            }

谢谢您的回复,我需要通过滑动操作或任何事件来添加视图,就像Swapps所做的那样。而不是在启动我的应用程序时添加视图,并通过一个动作事件来移除视图。 - ganesh
目前来说,我可以接受DjHacktor的答案,因为它非常接近我的要求。 - ganesh

2

使用窗口类型TYPE_PHONE替代TYPE_SYSTEM_OVERLAY,并搭配标志FLAG_NOT_FOCUSABLE


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:多点触控和TYPE_SYSTEM_OVERLAYTYPE_SYSTEM_OVERLAY内的GestureDetector。请尝试此Google搜索以获取更多信息。

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

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