Weex NavigationBar 设置

在开发weex时,如何较为完美的设置导航栏是我考虑了很久的问题。这篇文章是这2天学习内容的总结,主要包括了3个配置导航栏的方法:

  1. 整页开发,隐藏导航栏
  2. 采用weex提供的接口进行设置导航栏
  3. 在界面push之前,将导航栏的数据传给native进行设置

方法一:整页开发,隐藏导航栏

采用整页开发的方法,将原生自带的导航栏隐藏,然后自己在界面的顶部画一个导航栏,如下图所示:


iiehp-rvo0s.gif

主要有2个问题

  • 如上图所示,采用这种方法时,整个界面会先是白屏,当js下载,解析并渲染成功后,整个界面才会被显示出来,由于导航栏也是在js中实现的,所以整个导航栏也会等到界面渲染后才能呈
    现出来。
  • 进入第二界面时,会看到第一个界面导航栏隐藏的效果,第一个界面在进行转场动画时,顶部原先导航栏位置会变成白色背景。

方法二: 采用weex提供的接口进行设置导航栏

ps: 由于本人知识限制,暂时先讨论weex在iOS平台的设置,Android会在学习相关知识后补上。

weekSDK的版本是 0.17.0

根据weex的官方文档,采用cocoaPods将WeexSDK导入到项目中后,可以在项目中查看WeexSDK的源码实现。在Weex的源码中,我们可以找到几个和导航栏navigation有关的类,分别是WXComponent+NavigationWXNavigatorModule,WXNavigationDefaultImpl,WXNavigationProtocol这4个文件。

WXNavigationProtocol 主要定义了和导航栏相关的一些接口,包括了导航栏的隐藏,背景颜色,标题等。
WXComponent+Navigation 是组件基类的一个类别,在该类别中实现解析.vue文件中的导航栏设置。在WXComponent+Navigation.m文件中,可以找到- (void)_setupNavBarWithStyles:(NSMutableDictionary *)styles attributes:(NSMutableDictionary *)attributes方法,如下图所示。

从代码中可以看出,如果将一个组件的dataRole设置为navbar,那么该组件就会被识别为拥有导航栏配置信息的组件,sdk可以从该组件的属性中读取到导航栏的相关配置并进行相应的设置。如下面代码:

<template>
<div dataRole = "navbar" :style="{  backgroundColor: 'black' }"></div>
</template>
// 将导航栏的背景颜色设置为黑色

效果图如下

IMG_0292dd.PNG

从代码中可以看出可以直接进行设置的只有style中的backgroundColor属性,其他属性都没有找到相关的设置。这是由于weex将其他的一些配置如标题,左边按键,右边按键等都看成一个个item,在.vue中通过实现item的方式来显示导航栏上面的其他组件。

如果你要实现中间的标题,可以通过以下代码实现:

<template>

<div dataRole = "navbar" :style="{  backgroundColor: 'black' }">
    <text
      naviItemPosition="center"
      :style="{ color: 'red' }"
      class="center-text" value = "title"></text>
</div>

</template>

这段代码的作用是将导航栏的背景颜色设置为黑色,将导航栏的标题设置为title,颜色为红色。具体效果如下:

l671i-c8lan.gif

图中发现标题的颜色并没有改变,这是由于在weexSDK的WXNavigationDefaultImpl中,只是读取了标题的内容,并赋值给了navigationItemtitle,对于标题颜色并没有进行相应的设置

浏览整个WXNavigationDefaultImpl文件可以发现有个titleView方法生成了titleView并设置了字体的颜色,但是该函数并没有被任何对象调用。

WXNavigationDefaultImpl 主要是实现了WXNavigationProtocol协议的内容。

WXNavigatorModule主要是暴露一些设置导航栏的接口给js,如何调用native暴露的方法请查看官方文档,暴露的接口如下所示:

WX_EXPORT_METHOD(@selector(open:success:failure:))
WX_EXPORT_METHOD(@selector(close:success:failure:))
WX_EXPORT_METHOD(@selector(push:callback:))
WX_EXPORT_METHOD(@selector(pop:callback:))
WX_EXPORT_METHOD(@selector(setNavBarBackgroundColor:callback:))
WX_EXPORT_METHOD(@selector(setNavBarLeftItem:callback:))
WX_EXPORT_METHOD(@selector(clearNavBarLeftItem:callback:))
WX_EXPORT_METHOD(@selector(setNavBarRightItem:callback:))
WX_EXPORT_METHOD(@selector(clearNavBarRightItem:callback:))
WX_EXPORT_METHOD(@selector(setNavBarMoreItem:callback:))
WX_EXPORT_METHOD(@selector(clearNavBarMoreItem:callback:))
WX_EXPORT_METHOD(@selector(setNavBarTitle:callback:))
WX_EXPORT_METHOD(@selector(clearNavBarTitle:callback:))
WX_EXPORT_METHOD(@selector(setNavBarHidden:callback:))

使用weex提供的接口设置导航栏

weex的官方demo中,有对导航栏的配置进行简单封装,可以较为方便的实现导航栏的设置 传送门
include文件夹中还封装了很多常用组件

采用上面的方法对导航栏进行简单的设置,并采用navigator模块进行界面跳转,效果如下:

![lvqr5-gsvqm.gif](http://upload-images.jianshu.io/upload_images/1925310-dad9c6fbd7fdca9a.gif?imageMogr2/auto-orient/stri

zze8n-lqd1d.gif

如上图片所示,使用weex提供的方法是可以实现导航栏的设置的,会有以下2个问题
  • 当push一个新的界面是,是先进入了新的界面,等到js文件被解析后,才会修改导航栏的颜色和标题等属性,虽然进入界面就能看到导航栏,但和系统原生的对比,体验还不是很好。
  • 当从view2 返回 view1 时,view1显示的导航栏背景颜色是view2设置的导航栏背景颜色,解决这个问题的办法是在每一个.vue文件界面中监听viewappear事件,当界面显示时,重新修改导航栏的颜色。
    ps: 如果你的viewcontroller不是继承自WXBaseViewController 那么需要自己在viewcontroler的 viewDidAppear和viewDidDisappear中实现 调用[[WXSDKManager bridgeMgr] fireEvent:_instance.instanceId ref:WX_SDK_ROOT_REF type:@"viewdisappear" params:nil domChanges:nil] 来通知js层
优点
  • weexSDK中就实现了相应的接口,我们可以很方便在js层调用相应的方法来使用原生的导航栏,不需要额外工作

方法三:在界面push之前,将导航栏的数据传给native进行设置

如果想在js层能够设置导航栏并且交互体验上接近与原生,那就在每一个界面push出来之前,将导航栏的数据传递给native。实现这个需要以下几个要点:

  • 需要自己实现一个跳转模块,可以选择覆盖weex中的WXNavigationProtocol协议(可以自己实现WXNavigationProtocol协议并在注册,只要在调用initSDKEnvironment方法后面注册就行了),或者是自己实现一个简单的跳转module
  • 在跳转时,传输下一个界面的导航栏配置参数到native。
  • native在下个界面push出来之前,先将js传过来的数据进行解析,并对导航栏进行相应的配置。
  • native跳转出下个界面

实现跳转模块

这部分网上有很多教程,官方就提供了一个例子

传输导航栏配置信息

  1. 创建navigationBar相应的数据结构,这个结构可以依照个人的习惯配置,简单的配置可以如下:
{
    "View1.js":{
        "title":"view1",
        "navigationBarTintColor":"white",
        "background": {
          "color":"#00ff00"
        }
    },
    "view2.js":{
        "title":"view2",
        "navigationBarTintColor":"white",
        "background": {
          "color":"#00ff00"
        }
    }
}
  1. 根据跳转到的界面路径寻找对应的导航栏配置,并传输到native中
 push(path) {
        var bundleUrl = weex.config.bundleUrl;
        var arr = bundleUrl.split('/')
        arr.splice(arr.length-1,1,path)
        var totlePath = arr.join('/');
        console.log('-------vcnavigationInfos',navigationInfos);
        var navigationBarInfo = navigationInfos[path]
        var option = {
            'url': totlePath,
            'navigationBarInfo':navigationBarInfo
        }
        navigator.openURL(option, event => {
            
        })
    }
  1. native 端接收到配置文件后,进行相应的配置就可以了
- (void)openURL:(NSDictionary *)option callback:(WXModuleCallback)callback
{
    NSString *newURL = [option valueForKey:@"url"];
    if ([newURL hasPrefix:@"//"]) {
        newURL = [NSString stringWithFormat:@"http:%@", newURL];
    } else if (![newURL hasPrefix:@"http"]) {
        
    }
    NSDictionary *renderInfo = [option valueForKey:@"navigationBarInfo"];
    
    EPBaseViewController *viewController;
    viewController = [[EPBaseViewController alloc] initWithRenderInfo:renderInfo];
    
    (viewController).url = [NSURL URLWithString:newURL];
    [(QMUINavigationController*)((([UIApplication sharedApplication].keyWindow).rootViewController)) pushViewController:viewController animated:true];
    callback(@{@"result":@"success"});
}

实现效果图如下


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,013评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,205评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,370评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,168评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,153评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,954评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,271评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,916评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,382评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,877评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,989评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,624评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,209评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,199评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,418评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,401评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,700评论 2 345