栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【高级UI】【005】利用WindowManager创建自定义的PopupWindow和SystemAlertDialog

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【高级UI】【005】利用WindowManager创建自定义的PopupWindow和SystemAlertDialog

目标

本篇博客的目标主要有三个

  • 不使用安卓原生控件,比如PopupWindow,Dialog等控件,实现我们的目标
  • PopupWindow用于在Activity中全屏展示,模态,PopupWindow下面的全部内容不可操作,当Activity隐藏时,PopupWindow也随之隐藏
  • SystemalertDialog用于在整个系统中悬浮展示,非模态,SystemalertDialog下面的内容仍然可以操作,当Activity隐藏时,SystemalertDialog并不隐藏,它可以在系统桌面之上显示

注意,桌面悬浮框是需要申请额外权限的,需要在清单里注册"SYSTEM_alert_WINDOW"权限,并在应用设置里开启"允许在应用上层显示"功能

另外,默认情况下,Window中的ContentView,是不具备处理按键事件的功能的,如果我们需要监听返回键时关闭Window,需要自己重写一个ContentView

实现代码

	package com.android.architecture;
	
	import android.view.KeyEvent;
	
	public interface IKeyEventDispatcher {
	
	    boolean dispatchKeyEvent(KeyEvent event);
	
	    void setKeyEventListener(KeyEventListener listener);
	
	    interface KeyEventListener {
	        boolean dispatchKeyEvent(KeyEvent event);
	    }
	}

	package com.android.architecture;
	
	import android.content.Context;
	import android.util.AttributeSet;
	import android.view.KeyEvent;
	import android.widget.frameLayout;
	
	public class KeyEventframeLayout extends frameLayout implements IKeyEventDispatcher {
	
	    KeyEventListener listener;
	
	    public KeyEventframeLayout(Context context) {
	        super(context);
	    }
	
	    public KeyEventframeLayout(Context context, AttributeSet attrs) {
	        super(context, attrs);
	    }
	
	    public KeyEventframeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
	        super(context, attrs, defStyleAttr);
	    }
	
	    @Override
	    public void setKeyEventListener(KeyEventListener listener) {
	        this.listener = listener;
	    }
	
	    @Override
	    public boolean dispatchKeyEvent(KeyEvent event) {
	        if (listener == null)
	            return super.dispatchKeyEvent(event);
	        return listener.dispatchKeyEvent(event);
	    }
	}

    //显示应用内弹窗
    protected void showPopupWindow() {
        WindowManager windowManager = StartActivity.this.getSystemService(WindowManager.class);
        //设置window大小
        WindowManager.LayoutParams lpContent = new WindowManager.LayoutParams();
        lpContent.height = ViewGroup.LayoutParams.MATCH_PARENT;
        lpContent.width = ViewGroup.LayoutParams.MATCH_PARENT;
        lpContent.format = PixelFormat.RGBA_8888;
        lpContent.gravity = Gravity.CENTER;
        //设置window类型,这个同时也决定了window显示的优先级
        lpContent.type = WindowManager.LayoutParams.TYPE_base_APPLICATION;
        //设置窗体特性
        lpContent.flags = 0;
        lpContent.flags = lpContent.flags | WindowManager.LayoutParams.FLAG_DIM_BEHIND;
        lpContent.flags = lpContent.flags | WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
        //设置背景变暗程度
        lpContent.dimAmount = 0.6F;
        //创建ContentView
        KeyEventframeLayout contentView = new KeyEventframeLayout(StartActivity.this);
        //添加内容
        TextView textView = new TextView(StartActivity.this);
        textView.setText("Popup Window");
        textView.setTextColor(Color.WHITE);
        textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 30);
        frameLayout.LayoutParams lpChild = new frameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        lpChild.gravity = Gravity.CENTER;
        textView.setLayoutParams(lpChild);
        contentView.addView(textView);
        //监听返回事件
        contentView.setKeyEventListener(event -> {
            if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
                windowManager.removeView(contentView);
                return true;
            }
            return false;
        });
        //监听点击事件
        contentView.setOnClickListener(v -> {
            windowManager.removeView(contentView);
        });
        //显示window
        windowManager.addView(contentView, lpContent);
    }

    //显示系统悬浮框
    //注意,这个操作需要注册"SYSTEM_alert_WINDOW"权限,并开启"允许在应用上层显示"功能
    protected void showSystemalertDialog() {
        WindowManager windowManager = StartActivity.this.getSystemService(WindowManager.class);
        //设置window大小
        WindowManager.LayoutParams lpContent = new WindowManager.LayoutParams();
        lpContent.height = 400;
        lpContent.width = 400;
        lpContent.format = PixelFormat.RGBA_8888;
        lpContent.gravity = Gravity.TOP | Gravity.RIGHT;
        //设置window类型,这个同时也决定了window显示的优先级
        lpContent.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
        //设置窗体特性
        lpContent.flags = 0;
        lpContent.flags = lpContent.flags | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
        //创建ContentView
        //由于原生的frameLayout不能监听返回键,我们必须重写一个自己的frameLayout
        KeyEventframeLayout contentView = new KeyEventframeLayout(StartActivity.this);
        //添加内容
        TextView textView = new TextView(StartActivity.this);
        textView.setText("System alert Dialog");
        textView.setTextColor(Color.WHITE);
        textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 30);
        frameLayout.LayoutParams lpChild = new frameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        lpChild.gravity = Gravity.CENTER;
        textView.setLayoutParams(lpChild);
        contentView.addView(textView);
        //监听返回事件
        contentView.setKeyEventListener(event -> {
            if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
                windowManager.removeView(contentView);
                return true;
            }
            return false;
        });
        //显示window
        windowManager.addView(contentView, lpContent);
    }

WindowManager中常见Flag的作用

	//无法获得焦点,即无法接收到任何KeyEvent事件
	WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
	//无法触摸,即无法接收到任何MotionEvent
	WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
	//非模态,即不阻挡底部内容
	WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
	//背景变暗
	WindowManager.LayoutParams.FLAG_DIM_BEHIND;
	//全屏,即不显示状态栏和导航栏背景
	WindowManager.LayoutParams.FLAG_FULLSCREEN;
	//绘制状态栏和导航栏,如果不绘制,可能会出现导航栏空白现象
	WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/318301.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号