微信小程序之自定义导航栏 navigationStyle

本文有较强的时效性,小程序是在不断的完善,从不支持自定义导航栏,到支持全局自定义导航栏,再到现在的支持单页面配置。本文写作时调试基础库为2.7.0

自定义导航栏只需要在app.json 中的window 增加navigationStyle:custom 即可,默认的顶部导航栏会消失,只保留右上角胶囊状的按钮,胶囊按钮目前只支持黑色和白色两种颜色 在app.json 中的window 加上 "navigationBarTextStyle":"white/black"

小程序调试基础库2.4.3 之后就可以单页面单独配置了,不过从默认导航栏的页面跳到自定义导航栏的页面时可能会出现导航栏先消失再跳转的问题,开发的时候还是注意下,如果使用了自定义导航栏尽量所有页面都使用,当然web-view 页面现在还不支持自定义导航栏。

全局配置直接在app.json 中配置

{
  "usingComponents": {
    "navigationBar": "/components/navigationBar/navigationBar"
  },
  "window": {
    "navigationStyle": "custom"
  } 
}

如果单页面配置全局配置文件app.json 设置为default

{
  "window": {
    "navigationStyle": "default"
  } 
}

自定义页面的json 配置文件里。

{
  "navigationStyle": "custom",
  "usingComponents": {
    "navigationBar": "/components/navigationBar/navigationBar"
  }
}

新建components

navigationBar.js

const app = getApp()

Component({

  properties: {
    title: {
      type: String,
      value: 'Fatesinger'
    },
    back: {
      type: Boolean,
      value: false
    },
    home: {
      type: Boolean,
      value: false
    }
  },
  data: {
    statusBarHeight: app.globalData.statusBarHeight + 'px',
    navigationBarHeight: (app.globalData.statusBarHeight + 44) + 'px'
  },

  methods: {
    backHome: function () {
      let pages = getCurrentPages()
      wx.navigateBack({
        delta: pages.length
      })
    },
    back: function () {
      wx.navigateBack({
        delta: 1
      })
    },
    loading: {
      type: Boolean,
      value: false
    }
  }
})

navigationBar.wxss

这里的样式是白色导航栏,如需配套颜色注意修改。

增加了一个css3 加载动画,可以自行修改navBar-loader

.navbar {
  width: 100%;
  background-color: #fff;
  position: fixed;
  top: 0;
  left: 0;
  z-index: 999;
}
.title-container {
  height: 40px;
  display: flex;
  align-items: center;
  position: relative;
}
.capsule {
  margin-left: 10px;
  height: 30px;
  background: rgba(255, 255, 255, 0.6);
  border: 1px solid #eee;
  border-radius: 16px;
  display: flex;
  align-items: center;
}
.capsule > view {
  width: 45px;
  height: 60%;
  position: relative;
}
.capsule > view:nth-child(2) {
  border-left: 1px solid #eee;  
}
.capsule image {
  width: 20px;
  height: 20px;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-10px,-10px);
}
.title {
  position: absolute;
  top: 6px;
  left: 104px;
  right: 104px;
  height: 30px;
  line-height: 30px;
  font-size: 18px;
  text-align: center;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.navBar-loader {
	height: 18px;
	width: 18px;
	animation: loader-1-1 4.8s linear infinite;
  display: inline-block;
  margin-right: 4px;
  vertical-align: middle;
}

@keyframes loader-1-1 {
	0%   { transform: rotate(0deg); }
	100% { transform: rotate(360deg); }
}
.navBar-loader .inner {
	display: block;
	position: absolute;
	top: 0; left: 0;
	bottom: 0; right: 0;
	margin: auto;
	height: 18px;
	width: 18px;
	clip: rect(0, 18px, 18px, 9px);
	animation: loader-1-2 1.2s linear infinite;
}

@keyframes loader-1-2 {
	0%   { transform: rotate(0deg); }
	100% { transform: rotate(220deg); }
}
.navBar-loader .inner:after {
  
	content: "";
	position: absolute;
	top: 0; left: 0;
	bottom: 0; right: 0;
	margin: auto;
	height: 18px;
	width: 18px;
	clip: rect(0, 18px, 18px, 9px);
	border: 3px solid #ccc;
	border-radius: 50%;
	animation: loader-1-3 1.2s cubic-bezier(0.770, 0.000, 0.175, 1.000) infinite;
  z-index: 1000;
  box-sizing: border-box;
}

@keyframes loader-1-3 {
	0%   { transform: rotate(-140deg); }
	50%  { transform: rotate(-160deg); }
	100% { transform: rotate(140deg); }
}

navigationBar.wxml

因为导航栏使用了position:fixed,为了避免页面塌陷问题,直接添加了一个和导航栏等高的view

<view class="navbar" style="{{'height: ' + navigationBarHeight}}">
  <view style="{{'height: ' + statusBarHeight}}"></view>
  <view class='title-container'>
    <view class='capsule' wx:if="{{ back || home }}">
      <view bindtap='back' wx:if="{{back}}">
        <image src='/images/back.png'></image>         
      </view>
      <view bindtap='backHome' wx:if="{{home}}">
        <image src='/images/home_top.png'></image>
      </view>
    </view>
    <view class='title'><view wx:if="{{loading}}" class="navBar-loader"><view class="inner"></view></view>{{text}}</view>
  </view>
</view>
<view style="{{'height: ' + navigationBarHeight}};background: white;"></view>

图片放在images文件夹下,默认back.pnghome_top.png

navigationBar.json

{
  "component": true,
  "usingComponents": {}
}

直接使用

<navigationBar title="{{title}}" loading="{{true}}" home="{{true}}" back="{{true}}"></navigationBar>

调用即可。

input 输入框获得焦点会上推页面,导航栏也会被上推,而右上角的胶囊不会被上推。

解决方法input 标签adjust-position 设置为false,如果是固定在顶部的输入框,还需要对固定元素重新定位避免输入框被遮挡,这个时候需要获取弹出键盘高度,需要监听input 输入框的focusblur 事件,使用bindfocus,返回对象e.detail.height就是键盘高度,注意这个参数只有在真机中才有,模拟器中并没有。

Bigfa

computer loser / Travel with

可能感兴趣的文章

Responses

  1. 奶爸de笔记的头像

    :arrow: 不懂代码的也只能用免费开源的小程序代码撸一个了。

  2. looper的头像

    大佬 :mrgreen:

    1. mG的头像

      @looper 小姐姐 你的博客怎么做棋牌了 :oops:

    2. 狡猾的小猫咪的头像

      @mG 不好意思,忘了改,哈哈哈,做棋牌不是蛮好的么~ :wink:

  3. repostone的头像

    非技术的路过。

  4. 夜枫的头像

    自定义导航栏后scorll组件下拉变黑什么鬼?

    1. bigfa的头像

      @夜枫 下拉刷新好像是page 才可以吧。 :cry:

  5. 磐石的头像

    赞vvg

  6. linkstar的头像

    代码不全,遗漏了很多细节。

发表留言

人生在世,错别字在所难免,无需纠正。

:mrgreen::neutral::twisted::arrow::shock::smile::???::cool::evil::grin::idea::oops::razz::roll::wink::cry::eek::lol::mad::sad::!::?: Smilies powered by wp-alu

Post Comment