android studio 顶部导航栏_【uniapp】一个示例教你学会uniapp的导航栏开发

本文使用uni-app的原生导航栏和自定义导航栏两种形式,实现了一个简单的二级搜索页面功能, 大体上演示了uni-app的导航栏开发两种方式的区别。能力有限,仅做参考,感谢阅读~文章首发于一度的博客:https://hawkew.github.io,欢迎来踩~ 347b24adf8d1ef1c2c01dee1d02052f8.png

模拟一个需求

  • 一级搜索页输入关键词并点击搜索,将进入二级搜索页面并展示搜索结果。

  • 二级搜索页顶部导航不可输入,点击后返回一级搜索页

  • 使用nvue渲染,所以文件格式都为nvue

UI方案

效果预览

自定义导航栏

uni-app支持关闭原生导航栏 + 前端标签组件模拟导航栏进行开发,同时官方也强调自定义HTML组件模拟导航栏会有性能问题[1]。 官方的uni ui提供了自定义导航栏组件:NavBar 导航栏[2],其中提供了带搜索框的样式。 使用自定义导航栏的,优缺点如下:
  • 优点:更方便的自定义和动态修改

  • 缺点:官方说明中的性能问题

基本实现思路
  1. 页面style设置navigationStyle值为custom

  2. 手动HTML绘制导航栏或直接使用插件

主要代码
pages.json pages.json中配置页面navigationStylecustom
//pages.json{    "pages":[        {    "path": "pages/customTitle/customFirst",//一级搜索    "style": {        "navigationStyle":"custom"    }    },{    "path": "pages/customTitle/customSecond",//二级搜索    "style": {        "navigationStyle":"custom"    }    },    ]}
一级搜索页:
//customFirst.nvue                                                                                                      搜索            
二级搜索页: 实际配置与一级搜索页基本一致,只不过去除了右侧的搜索 。这里增加了一短代码模拟关键词搜索结果
//customFirst.nvue                                                                     测试关键词:{{keyword}}     
注意事项
  1. 页面设置为自定义导航栏时,需要设置一个status-bar的占位高度,否则内容会直接顶到顶部。nvue中可以通过获取状态栏高度+动态style的方式,其他模式可以直接使用uni-app的css变量[3] var(--status-bar-height)设置占位块的高度。

  1. 使用navBar插件实现导航栏搜索框,如果需要修改搜索框两侧占位button的宽度,修改uni-nav-bar.vue插件源码中的样式中uni-navbar__header-btns-leftuni-navbar__header-btns-rightuni-navbar__header-btns的宽度width值即可。如果你使用slot插槽去设置左右占位button的宽度,也可以直接注释掉这几个样式的width

原生导航栏

原生导航栏中的searchInputbackbuttonbuttons都是在pages.json中完成配置的。具体可见官方文档:导航栏[5] 优点:页面UI实现起来很方便。只需要对searchInputbackbuttonbuttons进行样式的配置即可 缺点:
  • 想要动态修改搜索框里的值,会很麻烦。官方并没有提供这样的API;在APP端需要通过H5+的webview修改,而H5端则需要通过修改dom的操作来执行。

  • 需要对不同端分别进行配置。如需要在APP端和H5端实现原生搜索框,则需要在style中分别对h5app-plus进行配置。

基本实现思路
页面style设置配置searchInput(中间的搜索框)和buttons(左边的返回和右边的搜索按钮)
主要代码
//originFirst.nvue//originSecond.nvuekeyword : {{keyword}}//pages.json{    pages:[          {      "path": "pages/originTitle/originTitle",      "style": {        "navigationBarBackgroundColor": "#1577fe",        "navigationBarTitleText": "uni-app",        "h5": {          "titleNView": {            "autoBackButton": true,            "backButton": {              "background": "#FFFFFF",              "color": "#FFFFFF",              "colorPressed": "#FFFFFF"            },            "searchInput": {              "align": "left",              "placeholder": "搜索",              "borderRadius": "5px",              "backgroundColor": "#FFFFFF",              "autoFocus": true            },            "buttons": [{              "color": "#FFFFFF",              "fontSize": "14px",              "text": "搜索"            }]          }        },        "app-plus": {          "titleNView": {            "backButton": {              "color": "#FFFFFF",              "colorPressed": "#FFFFFF"            },            "searchInput": {              "align": "left",              "placeholder": "搜索",              "borderRadius": "5px",              "backgroundColor": "#FFFFFF",              "autoFocus": true            },            "buttons": [{              "color": "#FFFFFF",              "fontSize": "14px",              "text": "搜索"            }]          }        }      }    ]}

动态修改

无论是自定义导航栏,还是uni-app的原生导航栏,都是可以进行样式修改的。 但是,就像之前提到过的那样,uni-app没有提供对searchInput进行修改的API,所以需要通过H5+等API或者直接修改dom等方式进行修改。

参数传递

回到需求中去,可以看到主要需要修改的内容为一级搜索页面和二级搜索页面的 searchInput 中展示的关键词。 这里,可以在一级页面和二级页面分别定义一个keyword,并通过uni-app的页面跳转传参来实现在不同页面keyword的赋值。 用户在一级搜索页面点击搜索,则执行search函数,通过带参数的uni.navigateTo实现一级页面到二级页面的传参。 而二级页面回到一级页面,uni.navigateBack无法传递参数,但是可以使用getCurrentPages()拿到上一个页面,调用页面的$set方法来修改上一个页面的keyword值。
//一级搜索页面data(){    return{        keyword:''    }},methods(){    search() {//点击搜索后运行        uni.navigateTo({            url:`./customSecond?keyword=${this.keyword}`        })    }}//二级搜索页面data(){    return{        keyword:''    }},onLoad(e){    this.keyword = e.keyword; //onLoad周期可以拿到上一个页面传过来的参数},methods(){    back(){//点击导航栏的输入框,或者回退button后运行        var pages = getCurrentPages();    var prevPage = pages[pages.length - 2]; //上一个页面    prevPage.$set(prevPage, "keyword", this.keyword)    uni.navigateBack()    }}

自定义导航栏

实现了参数的传递后,自定义导航栏的参数修改可以说是非常简单了。 在本例中,一级页面中的v-model="keyword"把搜索框的值传递给keyword,当搜索框的输入值变化时,keyword值也会同步变化。 而进入二级搜索页面时,可以通过输入框的:placeholder="keyword",直接就可以把keyword值赋值给inputplaceholder,在onLoad钩子拿到值之后,被被渲染到页面中。

原生导航栏

uni-app提供了一些页面生命周期函数[6] ,允许动态获取输入框的值,以及监听导航栏的相关事件
  • onNavigationBarSearchInputChanged:监听原生标题栏搜索输入框输入内容变化事件

  • onNavigationBarSearchInputConfirmed:监听原生标题栏搜索输入框搜索事件,用户点击软键盘上的“搜索”按钮时触发。

  • onNavigationBarSearchInputClicked:监听原生标题栏搜索输入框点击事件

  • onNavigationBarButtonTap:监听原生标题栏按钮点击事件,参数为Object

  • onBackPress:监听页面返回,返回 event = {from:backbutton、 navigateBack}backbutton 表示来源是左上角返回按钮或 android 返回键;navigateBack表示来源是 uni.navigateBack ;详细说明及使用:onBackPress 详解[7]

在一级搜索页面,可以在onNavigationBarSearchInputChanged钩子获取搜索框的输入值,并将其赋值给keyword;在onNavigationBarSearchInputConfirmedonNavigationBarButtonTap(点击搜索按钮)调用search函数,进行页面的跳转 在二级搜索页面的onNavigationBarSearchInputClicked,调用back()方法返回一级搜索页面。
APP端——H5+ API
官方示例 官方的uni-app在App端动态修改原生导航栏代码示例[8] 中,提供了相关的思路及api使用:
  1. 获取webView对象,通过webView的相关APIsetTitleNViewButtonStyle(修改导航栏按钮),setTitleNViewButtonBadge(修改导航栏按钮的角标),setTitleNViewSearchInputFocus(修改导航栏搜索框的focus状态)

  2. 通过currentWebviewgetStyle()setStyle()方法进行更新。

    详细的顶部标题栏相关的可修改样式,可以参考H5+ API--Webview[9]

  • WebviewTitleNViewStyles: 窗口标题栏控件样式

  • WebviewTitleNViewBackButtonStyles: 窗口标题栏自定义返回按钮样式

  • WebviewTitleNViewButtonStyles: 窗口标题栏自定义按钮样式

  • WebviewTitleNViewSearchInputStyles: 窗口标题栏搜索框样式

这篇官方的这篇示例文章是2018年的,代码中使用的webview的API已经更新,需要通过新的API去获取webView对象。示例代码更新后应该如下:
// #ifdef APP-PLUS  var webView = this.$mp.page.$getAppWebview();  var currentWebview = plus.webview.currentWebview();// 修改buttons  // index: 按钮索引, style {WebviewTitleNViewButtonStyles }  webView.setTitleNViewButtonStyle(0, {      text: 'hello',  });  // 修改按钮上的角标  // index: 按钮索引, text: 角标文本内容  webView.setTitleNViewButtonBadge({      index: 0,      text: 10,  });  // 设置 searchInput的 focus  // focus: true | false  webView.setTitleNViewSearchInputFocus(true)  // 设置 searchInput的 text  webView.setTitleNViewSearchInputText(text)  // searchInput 通过 webview 的 setStyle 方法进行更新  var tn = currentWebview.getStyle().titleNView;  if (tn.buttons) {    uni.getSystemInfo({        success:function(res){            if (res.platform=="ios") { // 这里在HBuilderX 1.9.9版本有个bug,searchInput的I变小写了 ,临时绕过下。更高版本会修复此bug                tn.searchinput.placeholder = 'test';                currentWebview.setStyle({                    titleNView: tn                });            } else{                tn.searchInput.placeholder = 'test'; //这里有个已知bug,HBuilderX 1.9.9上,当searchInput位于首页时,动态设置placehold会导致buttons的点击事件消失。更高版本会修复此bug                currentWebview.setStyle({                    titleNView: tn                });            }        }    })    }    // #endif
参考示例代码,APP端使用plus API修改一级页面的输入值:
var currentWebview = plus.webview.currentWebview();currentWebview.setTitleNViewSearchInputText(this.keyword);
修改二级搜索页面的placeholder
var currentWebview = plus.webview.currentWebview();currentWebview.setTitleNViewSearchInputFocus(false);var tn = currentWebview.getStyle().titleNView;if (tn) {    uni.getSystemInfo({        success: function(res) {            if (res.platform == 'ios') {                tn.searchInput.placeholder = this.keyword;                currentWebview.setStyle({                    titleNView: tn                });            } else {                tn.searchInput.placeholder = this.keyword;                currentWebview.setStyle({                    titleNView: tn                });            }        }    });}
H5端——DOM操作修改
JS模拟事件更新input:
function changeInput(dom, st) {    var evt = new InputEvent('input', {        inputType: 'insertText',        data: st,        dataTransfer: null,        isComposing: false    });    dom.value = st;    dom.dispatchEvent(evt);}
修改一级搜索页面搜索框值value
const page = document.querySelectorAll(".uni-input-input[type=search]")[0];changeInput(page,this.keyword)
直接修改二级搜索页面搜索框的placeholder
const page = document.querySelectorAll(".uni-input-input[type=search]")[0];pages.placeholder = this.keyword;
需要注意的是,在H5端修改dom,要在onReady进行更新,否则会被实例的默认值覆盖。

总结

对比下来,虽然原生导航栏:
  • uni-app声称具有更高的性能

  • 所有样式集中在pages.json中让页面代码看似让template中的代码简洁许多

但是:
  • 使用起来颇为复杂一旦涉及到导航栏参数的修改,则需要调用各种API拿到参数值或者去修改参数值

  • 对于不同端,可能还需要进行不同的代码去修改

而自定义导航栏:
  • 在动态设置方面给了很大的操作空间

  • 修改样式也更加简单

所以, 如果你的标题栏是静态配置的,那么原生导航栏是一个不错的选择; 如果你需要对标题栏的内容进行任何程度的修改,那么还是建议使用自定义导航栏进行导航栏的开发。

引用

[1] uni-app导航栏开发指南 ( https://ask.dcloud.net.cn/article/34921 ) [2] NavBar 导航栏( https://ext.dcloud.net.cn/plugin?id=52 ) [3] uni-app 页面生命周期函数( https://uni-app.dcloud.io/frame?id=%e9%a1%b5%e9%9d%a2%e7%94%9f%e5%91%bd%e5%91%a8%e6%9c%9f ) [4] uni-app css变量( https://uni-app.dcloud.io/frame?id=css%e5%8f%98%e9%87%8f ) [5] uni-app 导航栏 ( https://uniapp.dcloud.io/collocation/pages?id=app-titlenview ) [6] uni-app 页面生命周期 ( https://uni-app.dcloud.io/frame?id=%e9%a1%b5%e9%9d%a2%e7%94%9f%e5%91%bd%e5%91%a8%e6%9c%9f ) [7] onBackPress 详解 ( http://ask.dcloud.net.cn/article/35120 ) [8] uni-app在App端动态修改原生导航栏 ( https://ask.dcloud.net.cn/article/35374 ) [9] HTML5 中国产业联盟 > API Reference > webview ( http://www.html5plus.org/doc/zh_cn/webview.html#plus.webview )
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值