如何在 Android 中使叠加窗口视图可点击和可触摸



我正在尝试学习如何创建一个类似于Android中Facebook聊天头信使图标的覆盖窗口。

设法创建了以下类,它使我能够创建类似于 fb 聊天头的覆盖窗口视图。 但是,我在使用可点击侦听器和可触摸侦听器时遇到困难。如果我使用可点击侦听器,可触摸侦听器不起作用,反之亦然。

我希望覆盖窗口视图是可单击的,以便在我点击它时恢复应用程序,并且可以触摸以将图标移动到屏幕上的任何位置。

法典:

public class FloatingViewService extends Service {
private WindowManager mWindowManager;
private View mFloatingView;
@Override
public IBinder onBind(Intent intent) {
    return null;
}
@Override
public void onCreate() {
    super.onCreate();
    Log.d(TAG, "onCreate: Floating Service is create");
    //the xml file
    //Inflate the floating view layout we created
    mFloatingView = LayoutInflater.from(this).inflate(R.layout.layout_floating_widget, null);
    //Add the view to the window.
    final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.WRAP_CONTENT,
            LAYOUT_FLAG,
            WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
            PixelFormat.TRANSLUCENT);

    //Specify the view position
    params.gravity = Gravity.TOP | Gravity.LEFT;        //Initially view will be added to top-left corner
    params.x = 0;
    params.y = 100;
    //Add the view to the window
    mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
    mWindowManager.addView(mFloatingView, params);
    //The root element of the iconView view layout
    final View iconView = mFloatingView.findViewById(R.id.icon_view);

    //the icon view inside the xml file
    //Open the application on the tap click
    iconView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            //Open the application with click.
            Intent intent = new Intent(FloatingViewService.this, MyActivity.class);
            startActivity(intent);
            //close the service and remove view from the view hierarchy
            stopSelf();
        }
    });
    //Drag and move floating view using user's touch action.
    mFloatingView.findViewById(R.id.root_container).setOnTouchListener(new View.OnTouchListener() {
        private int initialX;
        private int initialY;
        private float initialTouchX;
        private float initialTouchY;

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    //remember the initial position.
                    initialX = params.x;
                    initialY = params.y;
                    //get the touch location
                    initialTouchX = event.getRawX();
                    initialTouchY = event.getRawY();
                    return true;
                case MotionEvent.ACTION_UP:
                    return true;
                case MotionEvent.ACTION_MOVE:
                    //Calculate the X and Y coordinates of the view.
                    params.x = initialX + (int) (event.getRawX() - initialTouchX);
                    params.y = initialY + (int) (event.getRawY() - initialTouchY);

                    //Update the layout with new X & Y coordinate
                    mWindowManager.updateViewLayout(mFloatingView, params);
                    return true;
            }
            return false;
        }
    });
}

@Override
public void onDestroy() {
    super.onDestroy();
    if (mFloatingView != null) mWindowManager.removeView(mFloatingView);
}
}
您可以在触发

ACTION_DOWN事件时记录当前时间,因此您可以执行所需的操作,例如在ACTION_UP事件中处理 onclick。

public class FloatingViewService extends Service {
    private WindowManager mWindowManager;
    private View mFloatingView;
    private long interval = 0;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "onCreate: Floating Service is create");
        //the xml file
        //Inflate the floating view layout we created
        mFloatingView = LayoutInflater.from(this).inflate(R.layout.layout_floating_widget, null);
        //Add the view to the window.
        final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                LAYOUT_FLAG,
                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                PixelFormat.TRANSLUCENT);

        //Specify the view position
        params.gravity = Gravity.TOP | Gravity.LEFT;        //Initially view will be added to top-left corner
        params.x = 0;
        params.y = 100;
        //Add the view to the window
        mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        mWindowManager.addView(mFloatingView, params);
        //The root element of the iconView view layout
        final View iconView = mFloatingView.findViewById(R.id.icon_view);

        //the icon view inside the xml file
        //Open the application on the tap click
        iconView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //Open the application with click.
                Intent intent = new Intent(FloatingViewService.this, MyActivity.class);
                startActivity(intent);
                //close the service and remove view from the view hierarchy
                stopSelf();
            }
        });
        //Drag and move floating view using user's touch action.
        mFloatingView.findViewById(R.id.root_container).setOnTouchListener(new View.OnTouchListener() {
            private int initialX;
            private int initialY;
            private float initialTouchX;
            private float initialTouchY;

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        interval = System.currentTimeMillis();
                        //remember the initial position.
                        initialX = params.x;
                        initialY = params.y;
                        //get the touch location
                        initialTouchX = event.getRawX();
                        initialTouchY = event.getRawY();
                        return true;
                    case MotionEvent.ACTION_UP:
                        if ((System.currentTimeMillis() - interval) < 300) {
                            // if time is less than 300 ms it means the user has clicked your view.
                            // handle your click here
                        } else {
                            //Calculate the X and Y coordinates of the view and update view
                            params.x = initialX + (int) (event.getRawX() - initialTouchX);
                            params.y = initialY + (int) (event.getRawY() - initialTouchY);

                            //Update the layout with new X & Y coordinate
                            mWindowManager.updateViewLayout(mFloatingView, params);
                        }

                        return true;
                    case MotionEvent.ACTION_MOVE:
                        //Calculate the X and Y coordinates of the view.
                        params.x = initialX + (int) (event.getRawX() - initialTouchX);
                        params.y = initialY + (int) (event.getRawY() - initialTouchY);

                        //Update the layout with new X & Y coordinate
                        mWindowManager.updateViewLayout(mFloatingView, params);
                        return true;
                }
                return false;
            }
        });
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mFloatingView != null) mWindowManager.removeView(mFloatingView);
    }
}

相关内容

  • 没有找到相关文章

最新更新