【JAVA UI】HarmonyOS的悬浮框实现

​参考资料

WindowManager

鸿蒙支持悬浮窗吗? WindowManager 的addComponent 不生效吗?

 

代码实现

1、准备工作

权限设置,我们需要在config.json文件上添加如下权限,代码如下

    "reqPermissions": [
      {"name": "ohos.permission.SYSTEM_FLOAT_WINDOW"}
    ],
2、绘画Xml布局

我们MianAbilitySlice的xml的布局,一个Text显示悬浮框,代码如下

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:height="match_parent"
    ohos:width="match_parent"
    ohos:alignment="center"
    ohos:orientation="vertical">

    <Text
        ohos:id="$+id:text_helloworld"
        ohos:height="match_content"
        ohos:width="match_content"
        ohos:background_element="$graphic:background_ability_main"
        ohos:layout_alignment="horizontal_center"
        ohos:text="显示悬浮框"
        ohos:text_size="40vp"
        />

</DirectionalLayout>

我们在绘画一个悬浮框的xml布局,命名为float_window.xml,然后在悬浮框中text组件用于显示悬浮的内容,代码如下

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:height="match_parent"
    ohos:width="match_parent"
    ohos:alignment="center"
    ohos:background_element="#20000000"
    ohos:orientation="vertical">

    <Text
        ohos:height="match_content"
        ohos:width="match_content"
        ohos:layout_alignment="horizontal_center"
        ohos:text="这个是一个悬浮框"
        ohos:text_size="40vp"
        />

</DirectionalLayout>

3、java 代码实现

text组件实现点击的事件,判断是否存在应用层显示权限,如果存在的话显示悬浮框,如果不存在的话关闭界面,代码如下

package com.aispeech.mileohos.slice;

import com.aispeech.mileohos.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.LayoutScatter;
import ohos.agp.window.service.Window;
import ohos.agp.window.service.WindowManager;
import ohos.sysappcomponents.settings.AppSettings;
import ohos.utils.net.Uri;
public class MainAbilitySlice extends AbilitySlice {
    private Window window;

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_main);
        //todo 设置点击事件
        findComponentById(ResourceTable.Id_text_helloworld).setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component view) {
                //todo 判断是否有在应用界面上显示的权限
                if (AppSettings.canShowFloating(MainAbilitySlice.this)) {
                    //todo 如果存在的话 显示悬浮框
                    show();
                } else {
                    //todo 如果不存在的话 添加设置界面进行设置
                    Intent intent2 = new Intent();
                    intent2.setAction("android.settings.action.MANAGE_OVERLAY_PERMISSION");
                    Uri parse = Uri.parse("package:" + getBundleName());
                    intent2.setUri(parse);
                    startAbilityForResult(intent2, 1000);
                }
            }
        });


    }
    @Override

    protected void onAbilityResult(int requestCode, int resultCode, Intent resultData) {
        boolean b = AppSettings.canShowFloating(this);
        System.out.println("songy 不给授权"+b);
        if (requestCode == 1000) {
            if (AppSettings.canShowFloating(this)) {
                show();
            }else {
                // todo 没授权 关闭界面
                terminateAbility();
            }
        }

    }

    /**
     * 悬浮框的实现
     */
    private void show(){
        //todo 加载悬浮框的布局
        ComponentContainer componentContainer = (ComponentContainer) LayoutScatter.getInstance(MainAbilitySlice.this).parse(ResourceTable.Layout_float_window,null,false);
     window=WindowManager.getInstance().
     addComponent(componentContainer,MainAbilitySlice.this,WindowManager.LayoutConfig.MOD_APPLICATION_OVERLAY);
        window.setTransparent(true);
        window.setMovable(true);
        WindowManager.LayoutConfig  layoutConfig=new WindowManager.LayoutConfig();
        //todo layoutConfig属性设置
        layoutConfig.width=900;
        layoutConfig.height=900;
        int flags = WindowManager.LayoutConfig.MARK_TOUCH_MODAL_IMPOSSIBLE |
                WindowManager.LayoutConfig.MARK_FOCUSABLE_IMPOSSIBLE |
                WindowManager.LayoutConfig.MARK_ALLOW_LAYOUT_COVER_SCREEN;
        layoutConfig.flags = flags;
        window.setLayoutConfig(layoutConfig);
    }

}

运行效果

%E7%9A%84%E7%82%B9%E7%82%B9%E6%BB%B4%E6%BB%B4.gif

欲了解更多更全技术文章,欢迎访问https://developer.huawei.com/consumer/cn/forum/?ha_source=zzh

posted @   华为开发者论坛  阅读(177)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
历史上的今天:
2021-08-10 如何解决应用安装失败错误码-13的问题
2021-08-10 华为应用市场AGC研习社直播:App个人信息安全保护审核标准解读
点击右上角即可分享
微信分享提示