问题

右上角的强制显示的微信默认菜单按钮挡住了界面。

1.png

方案

比较暴力的解决方法是整体下移一段距离避开这个区域即可。可不同机型这个区域的位置是不一样的,需要更优雅的解决方案。微信小游戏的官方API里有一个获取这个胶囊菜单区域的位置信息的函数:

wx.getMenuButtonBoundingClientRect()

获取菜单按钮(右上角胶囊按钮)的布局位置信息。坐标信息以屏幕左上角为原点。

返回值

Object
菜单按钮的布局位置信息

属性类型说明
widthnumber宽度,单位:px
heightnumber高度,单位:px
topnumber上边界坐标,单位:px
rightnumber右边界坐标,单位:px
bottomnumber下边界坐标,单位:px
leftnumber左边界坐标,单位:px

如何调用

因为我们是在白鹭引擎的框架里写游戏,所以需要在白鹭引擎中调用微信的这个API接口来获得位置信息。方法白鹭引擎也已经帮我们规划好了。
按照下面的流程一步一步来做。

修改白鹭引擎接口文件

白鹭引擎的src目录下有一个Platform.ts文件,打开它可以看到里面有一个interface和一个实现了这个interface的class。

declare interface Platform {
    getUserInfo(): Promise<any>;
    login(): Promise<any>
}

class DebugPlatform implements Platform {
    async getUserInfo() {
        return { nickName: "username" }
    }
    async login() {
    }
}

这个地方就是白鹭引擎为开发者准备的用来调用不同发布平台的API的地方。
里面已经写好了两个函数,我们不用理会。依葫芦画瓢,我们在里面加上我们需要的接口函数。
函数名不需要跟实际的API函数名一致,但我这里还是使用相同的函数名作为例子。
加上函数以后的样子:

declare interface Platform {
    getUserInfo(): Promise<any>;
    login(): Promise<any>

    // 获取菜单按钮(右上角胶囊按钮)的布局位置信息
    getMenuButtonBoundingClientRect(): Promise<any>
}

class DebugPlatform implements Platform {
    async getUserInfo() {
        return { nickName: "username" }
    }
    async login() {
    }

    // 获取菜单按钮(右上角胶囊按钮)的布局位置信息
    async getMenuButtonBoundingClientRect() {
    }
}

注意返回值不是any,而是Promise<any>,这是白鹭官方推荐的方法,关于什么是Promise请自行百度,不知道也问题不大,跟着我画瓢就行。
当然你也可以不使用Promise,直接返回any也是可以的。后面马上要讲到的函数实现的地方只要保持一致即可。

发布到微信开发者工具,在开发者工具里完成上述函数的具体实现

跟之前一样,保证egretProperties.json中的 target - current 已经设置为 wxgame 的前提下,点调试按钮即可自动发布到微信开发者工具中。项目根目录下有一个platform.js文件,这个文件在白鹭引擎的工程中是看不到的,只有发布到微信开发者工具中才有。我们需要在这个文件中完成我们添加的接口函数的具体实现。
打开这个文件可以看到白鹭引擎为我们实现了login和getUserInfo这两个接口的实现,我们不用理会。
还是照葫芦画瓢加上我们自己的函数实现:

class WxgamePlatform {
    login() {
        return new Promise((resolve, reject) => {
            // 省略...
        })
    }

    getUserInfo() {
        return new Promise((resolve, reject) => {
            // 省略...
        })
    }

    // 获取菜单按钮(右上角胶囊按钮)的布局位置信息
    getMenuButtonBoundingClientRect() {
        return new Promise((resolve, reject) => {
            // 这里是真正调用微信API的地方
            resolve(wx.getMenuButtonBoundingClientRect());
        })
    }
}

如果白鹭引擎那边的接口返回值用的是any,那么这里可以简单写成这样。(是不是感觉舒服多了)
当然,还是推荐用异步的Promise来传递返回值。自己斟酌。

    // 获取菜单按钮(右上角胶囊按钮)的布局位置信息
    getMenuButtonBoundingClientRect() {
        return wx.getMenuButtonBoundingClientRect();
    }

警告!
每次在白鹭引擎中点Debug按钮重新打包发布到微信开发者工具的时候platform.js会被默认内容覆盖掉。你辛辛苦苦写的函数就 不!见!了!
解决方案有两个:1-每次点debug按钮发布前备份一下platform.js,发布以后还原回来。2-不要点debug按钮,而是点编译按钮,亲测不会覆盖。

到这里接口就全部搞定了。下面实际调用一下试试。

在白鹭引擎ts里调用这个接口

  • 使用Promise作为返回值应该这样接收

    platform.getMenuButtonBoundingClientRect().then((retValue) => {
      egret.log("微信胶囊位置:left=" + retValue.left);
      egret.log("微信胶囊位置:bottom=" + retValue.bottom);
    });
  • 使用any作为返回值应该这样接收

    var retValue = platform.getMenuButtonBoundingClientRect();
    egret.log("微信胶囊位置:left=" + retValue.left);
    egret.log("微信胶囊位置:bottom=" + retValue.bottom);

有了这个位置,我们就可以愉快的避开它了。
这是完成的效果:
OK.png

Last modification:August 7, 2020
If you think my article is useful to you, please feel free to appreciate