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方法,如下图所示。

Weex NavigationBar 设置_第1张图片

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


// 将导航栏的背景颜色设置为黑色

效果图如下

Weex NavigationBar 设置_第2张图片
IMG_0292dd.PNG

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

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


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

l671i-c8lan.gif

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

Weex NavigationBar 设置_第3张图片

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

Weex NavigationBar 设置_第4张图片

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"});
}

实现效果图如下


你可能感兴趣的:(Weex NavigationBar 设置)