Android WindowManager工具类

WindowManager提供三个方法: addView()、updateLayout()、removeView()。分别对应是添加view、更新view、移除view。

    <!--悬浮窗权限-->
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

WindowManagerUtil 

package cn.jzvd.demo.utils;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.PixelFormat;
import android.hardware.display.DisplayManager;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;


import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * 注意申请悬浮窗权限
 */
public class WindowManagerUtil {

    private final String TAG = "GuiViewManager";
    private final List<WindowBean> mWindowBeans = new ArrayList<>();
    private static volatile GuiViewManager mInstance = null;
    private WindowBean mPreWindowBean;
    private Context mContext = null;
    private int mType = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;


    public void init(Context context) {
        mContext = context;
        createWindowManager();
    }

    public void setWindowType(int windowType) {
        mType = windowType;
    }


    private WindowManagerUtil() {

    }

    public static WindowManagerUtil getInstance() {
        if (mInstance == null) {
            synchronized (WindowManagerUtil.class) {
                if (mInstance == null) {
                    mInstance = new WindowManagerUtil();
                }
            }
        }
        return mInstance;
    }

    /**
     * 获取WindowManager
     *
     * @return
     */
    private void createWindowManager() {
        try {
            Display[] displays = ((DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE)).getDisplays();
            LogUtil.d(TAG,"displays.length " + displays.length);//displays.length<2说明只有一个屏幕
            if (null != displays) {
                for (Display display : displays) {
                    Context context = mContext.createDisplayContext(display);
                    WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
                    DisplayMetrics outMetrics = new DisplayMetrics();
                    windowManager.getDefaultDisplay().getMetrics(outMetrics);

                    WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
                    lp.type = mType;

                    lp.flags = WindowManager.LayoutParams.FLAG_FULLSCREEN
                            | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                            | WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS
                            | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;

                    //lp.width = WindowManager.LayoutParams.MATCH_PARENT;
                    //lp.height = WindowManager.LayoutParams.MATCH_PARENT;
                    lp.format = PixelFormat.TRANSPARENT;

                    //将alpha设置为最大遮挡不透明度
                    //lp.alpha = 0.8f;
                    lp.gravity = Gravity.TOP | Gravity.START;

                    mWindowBeans.add(new WindowBean(display.getDisplayId(), windowManager, lp));
                }
            }
        } catch (Exception e) {
            LogUtil.e(TAG,"createWindowManager  error " + e);
        }
    }

    /**
     * 获取状态栏高度
     *
     * @return
     */
    private int getStatusBarHeight() {
        int statusBarHeight = -1;
        //获取status_bar_height资源的ID
        @SuppressLint("InternalInsetResource")
        int resourceId = mContext.getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            //根据资源ID获取响应的尺寸值
            statusBarHeight = mContext.getResources().getDimensionPixelSize(resourceId);
        }
        return statusBarHeight;
    }

    public void show(View view, int width, int height, int startX, int startY) {
        //目前不考虑两个屏幕,在只有一个屏幕的情况下,displayId为0
        show(0, view, width, height, startX, startY);
    }

    public void show(int displayId, View view, int width, int height, int startX, int startY) {
        LogUtil.d(TAG, "show width " + width +" height " +height + " startX " + startX +" startY " +startY );
        try {
            WindowBean windowBean = getWindowBean(displayId);
            if (windowBean != null) {
                WindowManager windowManager = windowBean.getWindowManager();
                WindowManager.LayoutParams lp = windowBean.getLp();
                if (windowManager != null && lp != null) {
                    dismiss();

                    lp.x = startX;
                    lp.y = startY;
                    lp.width = width;
                    lp.height = height;
                    lp.type = mType;

                    windowManager.addView(view, lp);

                    windowBean.setView(view);
                    mPreWindowBean = windowBean;
                }
            }
        } catch (Exception e) {
            LogUtil.e(TAG, "show error ", e);
        }
    }

    public void dismiss() {
        if (mPreWindowBean != null) {
            WindowManager windowManager = mPreWindowBean.getWindowManager();
            View view = mPreWindowBean.getView();
            if (windowManager != null && view != null) {
                windowManager.removeView(view);
            }
            mPreWindowBean = null;
        }
    }

    public WindowBean getWindowBean(int displayId) {
        if (isEmptyArray(mWindowBeans)) {
            createWindowManager();
        }
        for (WindowBean windowBean : mWindowBeans) {
            if (displayId == windowBean.getDisplayId()) {
                return windowBean;
            }
        }
        return null;
    }

    private boolean isEmptyArray(Collection list) {
        return list == null || list.isEmpty();
    }

    public void destroy() {
        mWindowBeans.clear();
        mContext = null;
    }
}

WindowBean 

public class WindowBean {
    private int displayId;
    private WindowManager windowManager;
    private WindowManager.LayoutParams lp;
    private View view;

    public WindowBean(int displayId, WindowManager windowManager, WindowManager.LayoutParams lp) {
        this.displayId = displayId;
        this.windowManager = windowManager;
        this.lp = lp;
    }

    public int getDisplayId() {
        return this.displayId;
    }

    public WindowManager getWindowManager() {
        return this.windowManager;
    }

    public WindowManager.LayoutParams getLp() {
        return this.lp;
    }

    public View getView() {
        return this.view;
    }

    public void setView(View view) {
        this.view = view;
    }
}

其他工具类大家搜索一个就可以了。

推荐几个:

浮窗中addView()不显示 分析思路_android windowmanager addview后窗口不显示-CSDN博客

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Android中的WindowManagerAndroid系统中的一个关键类,它负责管理所有窗口的显示和布局。而悬浮球则是窗口中的一个小球,它可以随意拖动并悬浮在其他应用程序之上。 实现悬浮球的拖动可以通过以下步骤完成: 1. 创建一个悬浮球的View:首先需要创建一个自定义的View,用于显示悬浮球。这个View可以是一个小球的图片或者是一个自定义形状的View。 2. 添加悬浮球的权限:在AndroidManifest.xml文件中添加SYSTEM_ALERT_WINDOW权限,这是一项特殊权限,用于显示系统级别的悬浮窗口。 3. 创建悬浮球的WindowManager:通过WindowManager类的实例,可以获取到系统的WindowManager服务。 4. 将悬浮球的View添加到WindowManager中:使用WindowManager.LayoutParams参数来设置上述View的显示位置、大小、类型等属性,并通过WindowManageraddView方法将View添加到窗口中。 5. 监听悬浮球的触摸事件:为悬浮球的View设置触摸监听器,当用户按下悬浮球并移动手指时,通过更新悬浮球的LayoutParams参数的x和y属性来实现悬浮球的拖动操作。 6. 处理悬浮球的点击事件:为悬浮球的View设置点击监听器,当用户点击悬浮球时,可以执行相应的操作,如显示菜单、打开应用程序等。 7. 移除悬浮球的View:当不再需要显示悬浮球时,可以通过调用WindowManager的removeView方法将悬浮球的View从窗口中移除,并及时回收相关资源。 以上就是利用WindowManager实现Android悬浮球拖动的基本步骤。通过监听触摸事件和点击事件,可以实现悬浮球的拖动和响应用户操作的功能。同时,需要注意悬浮球的权限问题,以保证正确显示和操作悬浮球。 ### 回答2: Android WindowManager 悬浮球是一种常见的用户界面元素,常用于显示快捷方式、通知或其他常用功能。用户可以通过拖动悬浮球的方式来操作相关功能。 要实现悬浮球的拖动功能,首先需要创建一个悬浮球的视图,并将其添加到 WindowManager 中。可以通过创建一个继承自 View 的自定义悬浮球类来实现这一点。 在自定义悬浮球类中,需要重写 onTouchEvent() 方法以处理触摸事件。当用户按下悬浮球时,记录下手指按下的初始位置。当用户移动手指时,根据手指的移动距离来更新悬浮球的位置。可以使用 WindowManager.LayoutParams 的 x 和 y 属性来指定悬浮球的位置。 同时,还可以根据需要添加一些限制条件,如限制悬浮球的移动范围、限制悬浮球的吸附行为等。这些都可以通过对 MotionEvent 的处理来实现。 当用户松开手指时,悬浮球的拖动操作结束。此时,可以保存最后的位置信息以便下次使用。同时,还可以根据需要触发相应的功能操作,如打开一个快捷方式或显示一个通知等。 需要注意的是,要实现悬浮球的拖动功能,必须具有相应的权限。在 AndroidManifest.xml 文件中声明 SYSTEM_ALERT_WINDOW 权限,并在运行时请求该权限,以确保可以在其他应用程序上方显示悬浮球。 综上所述,通过自定义 View 类,重写 onTouchEvent() 方法,结合 WindowManager 的使用,可以实现 Android WindowManager 悬浮球的拖动功能。这样,用户就可以方便地通过拖动悬浮球来操作相关功能,并且可以根据实际需求对拖动行为进行定制。 ### 回答3: 在Android中,WindowManagerAndroid系统的一个重要组件,用于管理应用程序窗口的创建、显示和更新。悬浮球是一种常见的用户界面交互方式,它可以在屏幕上悬浮显示,并且可以通过拖动操作实现位置的改变。 实现悬浮球拖动的基本步骤如下: 1. 创建悬浮球视图:通过编程方式创建一个悬浮球视图,并设置其初始位置和样式。可以使用自定义的绘制工具或者使用现有的View类来实现悬浮球的外观。 2. 监听触摸事件:为悬浮球视图设置触摸事件的监听器,以便能够响应用户的触摸操作。可以通过重写onTouchEvent()方法来实现触摸事件的处理。 3. 处理触摸事件:在触摸事件的监听器中,根据不同的事件类型(如按下、移动、抬起),实现相应的逻辑。例如,当用户按下悬浮球时,记录下手指的初始位置;当用户移动手指时,根据手指的位置和初始位置计算悬浮球的新位置,并更新悬浮球的显示;当用户抬起手指时,完成悬浮球的拖动操作。 4. 更新悬浮球位置:在悬浮球拖动的过程中,需要不断更新悬浮球的位置。可以使用WindowManager的LayoutParams类来设置悬浮球的新位置,并通过WindowManager的updateViewLayout()方法来更新悬浮球的显示。 5. 处理边界情况:在处理悬浮球的拖动过程中,需要考虑到悬浮球是否超出屏幕边界的情况。可以通过判断悬浮球的位置,以及屏幕的大小来限制悬浮球的移动范围,避免悬浮球超出屏幕。 总之,通过使用WindowManager和触摸事件的监听器,可以实现Android中悬浮球的拖动功能。这个功能在许多应用中都很常见,例如一些工具类应用和游戏应用,可以增加用户的交互体验和便利性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值