Android自定义可移动悬浮窗,WindowManager.LayoutParams一些属性介绍

来源:互联网 发布:c语言发送post请求 编辑:程序博客网 时间:2024/06/05 14:39

效果图

效果图

thanks

WindowManager.LayoutParams详解

首先介绍一下常见的WindowManager.LayoutParams常量属性

layoutParams.flag

int类型 常量介绍 FLAGS_CHANGED 用于表示flags发生了变化 FLAG_ALLOW_LOCK_WHILE_SCREEN_ON 当该window对用户可见的时候,允许锁屏。 FLAG_BLUR_BEHIND 让该window后所有东西都模糊(blur) FLAG_DIM_BEHIND 让该window后所有的东西都成暗淡(dim) FLAG_DITHER 开启抖动(dithering) FLAG_FORCE_NOT_FULLSCREEN 恢复window非全屏显示 FLAG_FULLSCREEN 让window进行全屏显示 FLAG_KEEP_SCREEN_ON 当该window对用户可见时,让设备屏幕处于高亮(bright)状态。 FLAG_LAYOUT_IN_SCREEN 让window占满整个手机屏幕,不留任何边界(border) FLAG_LAYOUT_NO_LIMITS window大小不再不受手机屏幕大小限制,即window可能超出屏幕之外,这时部分内容在屏幕之外 FLAG_NOT_FOCUSABLE 让window不能获得焦点,这样用户快就不能向该window发送按键事件及按钮事件 FLAG_NOT_TOUCHABLE 让该window不接受触摸屏事件 FLAG_NOT_TOUCH_MODAL 即使在该window在可获得焦点情况下,仍然把该window之外的任何event发送到该window之后的其他window. FLAG_SECURE 当该window在进行显示的时候,不允许截屏。 FLAG_SHOW_WALLPAPER 在该window后显示系统的墙纸(wallpaper) FLAG_SHOW_WHEN_LOCKED 当锁屏的时候,显示该window. FLAG_TOUCHABLE_WHEN_WAKING 当手机处于睡眠状态时,如果屏幕被按下,那么该window将第一个收到到事件 FLAG_TURN_SCREEN_ON 当然window被显示的时候,系统将把它当做一个用户活动事件,以点亮手机屏幕。 FLAG_WATCH_OUTSIDE_TOUCH 如果你设置了该flag,那么在你FLAG_NOT_TOUNCH_MODAL的情况下,即使触摸屏事件发送在该window之外,其事件被发送到了后面的window,那么该window仍然将以MotionEvent.ACTION_OUTSIDE形式收到该触摸屏事件

layoutParams.type

类型 int 属性介绍 TYPE_APPLICATION 普通的应用程序window,token必须设置为Activity的token,以指出该窗口属谁 TYPE_APPLICATION_ATTACHED_DIALOG 对话框。类似于面板窗口,绘制类似于顶层窗口,而不是宿主的子窗口。 TYPE_APPLICATION_MEDIA 媒体窗口,例如视频。显示于宿主窗口下层。 TYPE_APPLICATION_PANEL 面板窗口,显示于宿主窗口上层 TYPE_APPLICATION_STARTING 用于应用程序启动时所显示的窗口。应用本身不要使用这种类型。它用于让系统显示些信息,直到应用程序可以开启自己的窗口 TYPE_APPLICATION_SUB_PANEL 应用程序窗口的子面板。显示于所有面板窗口的上层。(GUI的一般规律,越“子”越靠上) TYPE_BASE_APPLICATION 所有程序窗口的“基地”窗口,其他应用程序窗口都显示在它上面。 TYPE_INPUT_METHOD 内部输入法窗口,显示于普通UI之上。应用程序可重新布局以免被此窗口覆盖 TYPE_INPUT_METHOD_DIALOG 内部输入法对话框,显示于当前输入法窗口之上 TYPE_KEYGUARD 锁屏窗口 TYPE_KEYGUARD_DIALOG 锁屏时显示的对话框 TYPE_PHONE 电话窗口。它用于电话交互(特别是呼入)。它置于所有应用程序之上,状态栏之下。 TYPE_PRIORITY_PHONE 电话优先,当锁屏时显示。此窗口不能获得输入焦点,否则影响锁屏。 TYPE_SEARCH_BAR 搜索栏。只能有一个搜索栏;它位于屏幕上方。 TYPE_STATUS_BAR 状态栏类型的window。只能有一个状态栏window;它位于屏幕顶端,其他窗口都位于它下方。 TYPE_STATUS_BAR_PANEL 状态栏的滑动面板 TYPE_SYSTEM_ALERT 系统提示window,比如电池低的警告。它总是出现在应用程序窗口之上。 TYPE_SYSTEM_DIALOG 系统对话框。(例如音量调节框) TYPE_SYSTEM_ERROR 系统内部错误提示,显示于所有内容之上 TYPE_SYSTEM_OVERLAY 系统顶层窗口。显示在其他一切内容之上。此窗口不能获得输入焦点,否则影响锁屏。 TYPE_TOAST toast类型的window TYPE_WALLPAPER 用于墙纸的window

桌面浮窗权限申请

<usespermission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

此 权限6.0以上在清单文件注册没有效果,测试一下,就是动态申请权限也不能申请成功,只能用户手动开启,开启方法
权限预览

 if (Build.VERSION.SDK_INT >= 23) {            if (!Settings.canDrawOverlays(this)) {                Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,                        Uri.parse("package:" + getPackageName()));                startActivityForResult(intent, 10);            }        }

设置弹窗

  private void showWindow() {        WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();        layoutParams.width = 200;        layoutParams.height = 200;        layoutParams.gravity =  Gravity.CENTER_VERTICAL;        layoutParams.format = PixelFormat.TRANSPARENT;        layoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;        layoutParams.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_BLUR_BEHIND                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;        view = View.inflate(MainActivity.this, R.layout.window_view, null);        TextView textView= (TextView) view;        textView.setText("自定义弹窗");        manager.addView(view, layoutParams);        view.setOnTouchListener(new View.OnTouchListener() {//可以根据TouchView逻辑设置窗体跟着手指移动            @Override            public boolean onTouch(View v, MotionEvent event) {                return false;            }        });    }

移除弹窗

windowManager.removeView(view)

自定义跟着手指移动的View

package cn.evun.snakebardemo;import android.content.Context;import android.content.res.TypedArray;import android.support.design.widget.CoordinatorLayout;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.widget.TextView;/** */public class TouchView extends TextView {    private int downX;    private int downY;    private boolean isMove;    //屏幕密度    private float density = getResources().getDisplayMetrics().density;    public TouchView(Context context) {        super(context, null);    }    public TouchView(Context context, AttributeSet attrs) {        super(context, attrs);        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TouchView);        isMove = typedArray.getBoolean(R.styleable.TouchView_isMove, true);        typedArray.recycle();    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                //相对于控件左边缘的距离                downX = (int) event.getRawX();                downY = (int) event.getRawY();                break;            case MotionEvent.ACTION_MOVE:                int moveX = (int) event.getRawX();                int moveY = (int) event.getRawY();                int dx = moveX - downX;                int dy = moveY - downY;                CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) getLayoutParams();                layoutParams.leftMargin = layoutParams.leftMargin + (int) (dx * density);                layoutParams.topMargin = layoutParams.topMargin + (int) (dy * density);                setLayoutParams(layoutParams);                requestLayout();                downX = moveX;                downY = moveY;                break;            case MotionEvent.ACTION_UP:                break;        }        return isMove;    }}

源码传送

github

阅读全文
1 0
原创粉丝点击