場景:
項目中要求導航欄是漸變色/透明色衷恭,像下面這樣的效果:
微信官方提供的導航欄只支持純色,是無法實現(xiàn)上述效果的纯续。
解決方案:
微信小程序?qū)Ш綑谔峁┝藘煞N樣式:一種是默認樣式随珠,就是支持純色的那種;另一種是自定義樣式猬错,既然是自定義窗看,那我們就可以為所欲為了。嘿嘿
為了節(jié)約時間倦炒,在網(wǎng)上搜了一下微信小程序的自定義導航欄烤芦,果然已經(jīng)有大佬為我們實現(xiàn):https://blog.csdn.net/qq_33744228/article/details/83656588 但是僅支持純色和透明色,并且每個頁面都要做適配(導航欄會覆蓋頁面內(nèi)容析校,不同高度的導航欄要設置不同的“padding-top”)构罗。
為了滿足項目要求,在大佬的代碼基礎上擴充了如下功能:
1智玻、支持漸變色:
利用CSS3提供的線性漸變(linear-gradient)實現(xiàn):
-webkit-linear-gradient( [<point> || <angle>,]? <stop>, <stop> [, <stop>]* )
-webkit-
: 表示適配webkit內(nèi)核的瀏覽器遂唧;
[<point> || <angle>,]?
: 表示漸變的起始位置;
<stop>, <stop> [, <stop>]*
: 表示漸變的顏色吊奢;
例如:
background: -webkit-linear-gradient(top, orange, blue);
表示背景色從頂部開始由橙色漸變?yōu)樗{色盖彭。
2纹烹、組件內(nèi)適配所有機型:
可以認為導航欄有兩部分組成:狀態(tài)欄+標題欄。不同的機型狀態(tài)欄高度可能不同(除了劉海屏狀態(tài)欄高度是44之外召边,其他手機狀態(tài)欄高度都是20)铺呵,但標題欄高度都是44。微信小程序為我們提供了獲取狀態(tài)欄高度的方法:
wx.getSystemInfoSync().statusBarHeight
所以導航欄的高度為:
wx.getSystemInfoSync().statusBarHeight + 44
由于我們自定義的導航欄使用固定定位實現(xiàn)的隧熙,所以他就脫離了文檔流片挂,組件放進去后,會懸浮在上面贞盯,遮擋了下面的內(nèi)容音念,這時候就需要給父元素加個“padding-top”,“padding-top”的值即是導航欄的高度值躏敢。這部分可以寫到組件內(nèi)部實現(xiàn)闷愤,不用在每個頁面都做一次適配。
具體實現(xiàn):
通過自定義組件實現(xiàn)件余,具體怎么自定義組件讥脐,可以參考官方文檔:《自定義組件》。
一般自定義組件由 json wxml wxss js 4個文件組成啼器,我這里為了方便實現(xiàn)旬渠,多加了兩個文件:“back.png” 和 “navigation.wxs”:
“back.png”是導航欄的返回圖標;“navigation.wxs”是為了處理漸變這種邏輯镀首,需要漸變的顏色可以以一個數(shù)組形式傳進來,使用比較方便鼠次。如果其他項目需要使用更哄,只需要把navigation目錄拖到項目中即可。下面直接貼出具體的實現(xiàn)代碼:
navigation.json:
{
"component": true,
"usingComponents": {}
}
navigation.wxml:
<wxs src="navigation.wxs" module="nav">
</wxs>
<view style="padding-top:{{content_offset ? bar_Height + 44 : 0}}px;">
<view class='navigation status-bar'>
<view class='goBack' bindtap='goBack' style="padding-top:{{bar_Height}}px;" hidden='{{!show_bol}}'> <!-- 返回按鈕 -->
<image src='back.png'></image>
</view>
<view class="tabar {{my_class ? 'tabar2':''}}" style="padding-top:{{bar_Height}}px; background-color:{{background_color}}; {{nav.linearGradient(linear_gradient, direction, color_stops)}}">
<text style="color:{{title_color}};">{{title}}</text> <!-- 標題 -->
</view>
</view>
</view>
navigation.wxss:
/* 頂部導航 */
.navigation.status-bar {
width: 100%;
z-index: 99998;
position: fixed;
top: 0;
}
.navigation.status-bar .goBack{
position: absolute;
top: 7.5px;
font-size:12pt;
}
.navigation.status-bar .goBack image{
width: 22px;
height: 22px;
padding: 6px 20px 0 15px;
}
.navigation.status-bar .tabar {
display: flex;
justify-content: center;
background: #fff;
}
.navigation.status-bar .tabar2{
background: transparent !important;
}
.navigation.status-bar .tabar2 text{
color: #fff !important;
/* font-weight: lighter !important; */
}
.navigation.status-bar .tabar text {
height: 44px;
line-height: 44px;
/* padding: 10pt 15pt; */
color: #fff;
font-size: 17px;
/* font-weight: bold; */
}
.navigation.status-bar .tabar .active {
color: #fff;
}
navigation.js:
Component({
/* 組件的屬性列表 */
properties: {
title: { // 設置標題
type: String,
value: ''
},
title_color: { // 設置標題顏色
type: String,
value: '#fff'
},
show_bol: { // 控制返回箭頭是否顯示
type: Boolean,
value: true
},
my_class: { // 控制樣式(背景是否透明)
type: Boolean,
value: false
},
background_color: {//背景顏色
type: String,
value: "#24AFFF"
},
linear_gradient: { //是否漸變
type: Boolean,
value: true
},
direction: { //顏色漸變方向
type: String,
value: "top"
},
color_stops: { //漸變的起止顏色數(shù)組
type: Array,
value: ["#24AFFF", "#EEE"]
},
content_offset: { //內(nèi)容是否偏移(不讓導航欄遮擋內(nèi)容)
type: Boolean,
value: true
}
},
/* 組件的初始數(shù)據(jù) */
data: {
type: "組件",
bar_Height: wx.getSystemInfoSync().statusBarHeight // 獲取手機狀態(tài)欄高度
},
/* 組件的方法列表 */
methods: {
goBack: function () { // 返回事件
console.log("退后")
wx.navigateBack({
delta: 1,
})
}
}
})
navigation.wxs:
var linearGradient = function (isLinearGradient, direction, colorStops) {
if (isLinearGradient) {
return 'background: -webkit-linear-gradient(' + direction + ',' + colorStops.join(",") + ');';
}
return '';
}
module.exports = {
linearGradient: linearGradient
}
下拉刷新問題:
這樣實現(xiàn)的導航欄腥寇,下拉刷新的動畫(三個小圓點)是從屏幕頂部開始的成翩,下拉距離不夠大時會被導航欄給蓋住。而使用默認的導航欄赦役,下拉刷新動畫是從導航欄底部開始的麻敌,不會被蓋住。