首先鄙视一波互相复制黏贴的博主,代码都跑不通就往上贴

下面进入正题

我们要实现一个随手指滑动的浮窗可以分为以下几个步骤

1.我们首先要具体实现浮窗的自定义功能的View,

2.将浮窗设置到所有的应用的上方(设置选项的说法,直接点就是显示在桌面上)

3.随手指滑动的逻辑处理

现在我们来一步一步的实现

第一步:由于我们主要实现的功能是为了让这个玩意跟着手指动,所以第一步我们就用最简单的方法,直接放一个TextView;

TextView floatText = new TextView(context);
floatText.setText("这明显是一个浮窗");

第二部:将浮窗添加到桌面上,我们先来总览一下大概的需要的代码

public void buildFloatView() {
    //拿到所需的 WindowManager对象,我们必须要使用它管理浮窗
    final WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);

    // 构建悬浮中窗要放入的控件
    //这里你直接放入第一步中建立的TextView就可以了
    final FloatPreviewView floatPreviewView = new FloatPreviewView(this);
    floatPreviewView.setActivity();

    // 设置LayoutParam
    final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
    } else {
        layoutParams.type = WindowManager.LayoutParams.TYPE_PHONE;
    }
    //这里设置不拦截空白地方的点击事件
    layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
    //设置图位格式,有需要可以具体查阅官方文档
    layoutParams.format = PixelFormat.TRANSPARENT;
    //宽
    layoutParams.width = 400;
    //高
    layoutParams.height = 400;
    //x轴位置
    layoutParams.x = xPlace;
    //y轴位置
    layoutParams.y = yPlace;
    // 将悬浮窗控件添加到WindowManager
    windowManager.addView(floatPreviewView, layoutParams);
}

只要这一个方法,浮窗便会出现在你的桌面上了,当然必须要有浮窗需要的权限,这个权限在6.0之后要手动申请,具体方法这里不予赘述了,测试的话直接先在设置里面开启应急.

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

这里不推荐使用大家使用TYPE_TOAST属性,虽然这个属性会让你在一些低版本的机型中越过权限限制,但是这种不告而拿的行为很被用户厌烦

当你看到桌面上这个浮窗时,问题依然解决一半,那么我们继续开看下一半,怎么滑呢?

这里我们可以使用Android事件的触发机制来处理对手指滑动的监听

我们先来总览一下代码

private static final int MOVE_REACH_PIXEL = 10;

private int LAST_TOUCH_ACTION;

private float downX = 0;
private float downY = 0;

private float xNewSize = 0;
private float yNewSize = 0;
floatPreviewView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN: //手指按下触发
                        LAST_TOUCH_ACTION = MotionEvent.ACTION_DOWN;//设置状态为按下

                        //判断是不第一次按下,不然的话每重新滑动都会回到起点
                        //0这个值应该跟随你的初始位置变化
                        if (downX == 0 && downY == 0) { 
                            downX = event.getRawX();
                            downY = event.getRawY();
                        }
                        xNewSize = event.getRawX();
                        yNewSize = event.getRawY();
                        return true;
                    case MotionEvent.ACTION_MOVE: //手指滑动时触发,未来不让其触发太快,我们做一个降精度处理
                        //当X轴或Y轴的滑动大于10时再,判定为滑动,正好点击事件也需要这个
                        if (Math.abs(event.getRawX() - xNewSize) > MOVE_REACH_PIXEL
                                || Math.abs(event.getRawY() - yNewSize) > MOVE_REACH_PIXEL) {
                            LAST_TOUCH_ACTION = MotionEvent.ACTION_MOVE;//设置状态为滑动

                            //这里给定滑动的位置
                            layoutParams.x = (int) (xNewSize - downX); 
                            layoutParams.y = (int) (yNewSize - downY);
                            
                            //记录下最新一个点的位置
                            xNewSize = event.getRawX();
                            yNewSize = event.getRawY();
                            windowManager.updateViewLayout(floatPreviewView, layoutParams);
                        }
                        return false;
                    case MotionEvent.ACTION_UP:
                        if (LAST_TOUCH_ACTION == MotionEvent.ACTION_DOWN) {//如果触发了滑动就不是点击事件
                            //这里处理点击事件,未做长按处理,长点,短点都是点击,
                        }
                        return false;
                }
                return false;
            }
        });

到这里,view就能大致跟着你的手指滑动了