原生开发悬浮窗 移动和支持 缩放

148 阅读1分钟

原生开发悬浮窗 移动和支持 缩放

这里需要一些res 文件的准备 和xml 文件声明 res 中准备 layout

package com.demo;

import android.app.Service;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;

public class FloatingWindowService extends Service {

    private WindowManager windowManager;
    private View floatingView;
    private int initialX;
    private int initialY;
    private float initialTouchX;
    private float initialTouchY;
    private float initialDistance;
    private float initialScale = 1f;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();

        windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);

        floatingView = LayoutInflater.from(this).inflate(R.layout.float_app, null);

        WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
                PixelFormat.TRANSLUCENT
        );

        params.flags = params.flags | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;

        params.x = 0;
        params.y = 0;

        floatingView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getActionMasked()) {
                    case MotionEvent.ACTION_DOWN:
                        initialX = params.x;
                        initialY = params.y;
                        initialTouchX = event.getRawX();
                        initialTouchY = event.getRawY();
                        return true;
                    case MotionEvent.ACTION_POINTER_DOWN:
                        initialDistance = getDistance(event);
                        return true;
                    case MotionEvent.ACTION_MOVE:
                        if (event.getPointerCount() >= 2) {
                            float currentDistance = getDistance(event);
                            float delta = currentDistance - initialDistance;
                            float scale = initialScale + delta * 0.01f;
                            floatingView.setScaleX(scale);
                            floatingView.setScaleY(scale);
                        } else {
                            params.x = initialX + (int) (event.getRawX() - initialTouchX);
                            params.y = initialY + (int) (event.getRawY() - initialTouchY);
                            windowManager.updateViewLayout(floatingView, params);
                        }
                        return true;
                    case MotionEvent.ACTION_UP:
                        SharedPreferences sharedPreferences = getSharedPreferences("FloatingWindowPrefs", MODE_PRIVATE);
                        SharedPreferences.Editor editor = sharedPreferences.edit();
                        editor.putInt("x", params.x);
                        editor.putInt("y", params.y);
                        editor.putFloat("scale", floatingView.getScaleX());
                        editor.apply();
                        return true;
                }
                return false;
            }

            private float getDistance(MotionEvent event) {
                float dx = event.getX(0) - event.getX(1);
                float dy = event.getY(0) - event.getY(1);
                return (float) Math.sqrt(dx * dx + dy * dy);
            }
        });

        windowManager.addView(floatingView, params);
    }

    public int onStartCommand(Intent intent, int flags, int startId) {
        if (intent != null && intent.getExtras() != null) {
            String paramValue = intent.getStringExtra("paramKey");
        }
        return START_STICKY;
    }

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