小程序自定义导航栏适配(完美版)

阅读: 评论:0

小程序自定义导航栏适配(完美版)

小程序自定义导航栏适配(完美版)

1、发现问题

    小程序页面自定义导航栏功能已经开放有些日子了(还不知道这个功能的可以先>>了解一下),这极大的提升了小程序开发的自由度,相信不少小伙伴已经使用过这个功能,同时也相信不少小伙伴在此功能开发过程中踩过同样的一些坑:

  1. 机型多如牛毛:自定义导航栏高度在不同机型始终无法达到视觉上的统一;
  2. 调皮的胶囊按钮:导航栏元素(文字,图标等)怎么也对不齐那该死的胶囊按钮;
  3. 各种尺寸的全面屏,奇怪的刘海屏,简直要抓狂。
同样的,这些问题也是小灰经历过的。但是小灰相信,办法总比问题多,于是开始了自己的探究:

2、一探究竟

    为了搞明白到底该怎么去适配,老规矩,我先翻了一波官方文档,还别说,官方还真有这么一段介绍了相关细节,>>详情点击:


从图中分析,我们可以得到如下信息:

  1. Android跟iOS有差异,表现在顶部到胶囊按钮之间的距离差了6pt
  2. 胶囊按钮高度为32pt, iOS和Android一致

这。。。,好像并没有什么L用啊??这仅仅是普通屏幕为参照的,ipx, 安卓全面屏完全没介绍。

沉着冷静,我们接着分析:

  1. 胶囊按钮到状态栏下边缘这块距离,好像是固定的?
  2. 安卓这个图,好像有点奇怪?导航栏分为 状态栏+标题栏?
如果车两个条件成立,那我们的问题是不是就解决了80%了?

那么我们来论证一下:

第一个问题:胶囊按钮到状态栏下边缘的距离是不是固定的

  • 很简单,我们写一个状态栏,通过wx.getSystemInfoSync().statusBarHeight设置高度
  • 为了好测量,我们设置状态栏背景色为深色
js代码:

    var sysinfo = wx.getSystemInfoSync();this.setData({ statusBarHeight:sysinfo.statusBarHeight })复制代码

wxml代码:

<view class="status-bar" style="height:{{statusBarHeight}}px"></view>复制代码

wxss代码:

.status-bar{    background: rgb(141, 71, 71);}复制代码

效果图(iPhone6):


效果图(iPhoneX):


效果图(安卓):


是不是有点眉目了?是的,从截图可以看出,iOS是一致的,但是Android好像有所差别。

那究竟距离是多少?我们用神器(微信截图)来量一量:

Android:


iOS:


可以看出,iOS胶囊按钮与状态栏之间距离为:6px, Android为8px,并且经过测量,iOS各机型,Android各机型结果一致(由于篇幅原因,就不一一展示截图了,有兴趣的可以自行测量)

第二个问题:导航栏分为 状态栏+标题栏?

    通过对第一个问题的论证,很明显能看出来确实是这样的。并且通过第一个问题的测量结果以及官方提供的数据,我们可以对标题栏高度进行计算:

导航栏高度 = 胶囊按钮高度 + 状态栏到胶囊按钮间距 * 2                                                                Android导航栏高度 = 32px + 8px * 2 = 48px                                                                                        iOS导航栏高度 = 32px + 6px * 2 = 44px

*注:由于胶囊按钮是原生组件,为表现一致,其单位在个系统都为px,所以我们的自定义导航栏各个高度的单位都必需是px(切记不能用rpx),才能完美适配。


3、解决问题

通过上述分析,相信小伙伴们都能有一个解决问题的思路了,在上代码之前,小灰再给大家画一下重点:

  • 写自定义导航组件的时候,需要将组件结构一分为二:状态栏 + 标题栏
  • 状态栏高度可通过wx.getSystemInfoSync().statusBarHeight获取
  • 标题栏高度:安卓:48px,iOS:44px
  • 单位必需跟胶囊按钮一致,用px
话不多说,上代码( gitHub地址):

js:

Component({   properties: {        background: {            type: String,            value: 'rgba(255, 255, 255, 1)'        },        color: {            type: String,            value: 'rgba(0, 0, 0, 1)'        },        titleText: {            type: String,            value: '导航栏'        },        titleImg: {            type: String,            value: ''        },        backIcon: {            type: String,            value: ''        },        homeIcon: {            type: String,            value: ''        },        fontSize: {            type: Number,            value: 16        },        iconHeight: {            type: Number,            value: 19       },        iconWidth: {            type:Number,            value: 58        }    },    
attached: function(){        var that = this;        that.setNavSize();        that.setStyle();    },    data: {},    
methods: {        
// 通过获取系统信息计算导航栏高度        
setNavSize: function() {            
var that = this                , sysinfo = wx.getSystemInfoSync()                , statusHeight = sysinfo.statusBarHeight                , isiOS = sysinfo.system.indexOf('iOS') > -1                , navHeight;            
if (!isiOS) {                navHeight = 48;            } else {                navHeight = 44;            
}            
that.setData({                status: statusHeight,                navHeight: navHeight            })        
},        
setStyle: function() {            var that  = this                , containerStyle                , textStyle                , iconStyle;            containerStyle = [                'background:' + that.data.background                ].join(';');            textStyle = [                'color:' + lor,                'font-size:' + that.data.fontSize + 'px'            ].join(';');            iconStyle = [                'width: ' + that.data.iconWidth + 'px',                'height: ' + that.data.iconHeight + 'px'            ].join(';');            that.setData({               containerStyle: containerStyle,                textStyle: textStyle,                iconStyle: iconStyle            })        },        // 返回事件        
back: function(){            wx.navigateBack({                delta: 1            })            iggerEvent('back', {back: 1})        
},        
home: function() {            iggerEvent('home', {});       }   }})复制代码

wxml:

<view class='nav' style='height: {{status + navHeight}}px'>    
<view class='status' style='height: {{status}}px;{{containerStyle}}'></view>    <view class='navbar' style='height:{{navHeight}}px;{{containerStyle}}'>        <view class='back-icon' wx:if="{{backIcon}}" bindtap='back'>                    <image src='{{backIcon}}'></image>       </view>        
<view class='home-icon' wx:if="{{homeIcon}}" bindtap='home'>            <image src='{{homeIcon}}'></image>        
</view>        
<view class='nav-icon' wx:if="{{titleImg}}">            
<image src='{{titleImg}}' style='{{iconStyle}}'></image>       </view><view class='nav-title' wx:if="{{titleText && !titleImg}}"><text style='{{textStyle}}'>{{titleText}}</text></view></view>
</view>复制代码

wxss:

.navbar{    position: relative}.back-icon, .home-icon{    width: 28px;    height: 100%;    position: absolute;    transform: translateY(-50%);    top: 50%;    display: flex;}.back-icon{    left: 16px;}.home-icon{    left: 44px}.back-icon image{    width: 28px;    height: 28px;    margin: auto;}.home-icon image{    width: 20px;    height: 20px;    margin: auto;}.nav-title, .nav-icon{    position: absolute;    transform: translate(-50%, -50%);    left: 50%;    top: 50%;    font-size: 0;    font-weight: bold;}复制代码

运行效果图:

文字标题:



图片标题:



4、总结

经过小灰的一番论证以及实践经验,最终总结出以上最终解决方案,但希望对小伙伴们有所帮助,如果小伙伴们觉得有用,记得给颗star哦 --> 点我,后续还会更新其他组件。

如果大家有更好的方案或者觉得小灰的方案有问题,欢迎大家留言。


转载于:

本文发布于:2024-01-31 04:44:20,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170664745925586.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:自定义   完美版   程序   栏适配
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23