NavigatorLayout 导航布局

1. 概述

1.0 开始加入
涂鸦设备控制面板几乎不会是由单个页面组成, 组织和管理多个页面之间的关联, 嵌套关系, 以及页面之间如何过渡的组件,我们通常称之为Navigator.
NavigatorLayout就是一个支持导航路由的基础布局, 能轻易的处理面板页面间的切换.
默认NavigatorLayout集成了常用的最佳实践,比如FullView, OfflineViewTopBar, 同时保留了扩展性,这些组件均允许用户替换.
FullView封装了设备控制面板页面常用的组件布局,包括工具栏(TopBar), 遮罩层(MaskView), 离线视图(OfflineView)和背景(Background)
FullView默认会铺满父容器(flex: 1), 配合NavigatorLayout 导航布局使用,会铺满从状态栏底部虚拟按键之间的所有区域, 没有虚拟按键的设备,会铺满状态栏至屏幕底部的区域。
FullView没有直接开放给用户,NavigatorLayout默认集成了FullView, 同时保留了扩展点,允许用户自定义FullView视图传入
OfflineView是涂鸦提供的默认离线视图,如果没有特殊要求,默认的OfflineView已经适用大部分面板场景.
NavigatorLayout底层使用的Navigator文档可以在这里看到: 查看 React Native Navigator 文档

2. 基础使用

使用NavigatorLayout, 需要以下步骤
  1. 写一个React组件,继承tuya-panel-kit提供的NavigatorLayout
  2. 重写renderScene方法以渲染用户自己的页面, 需要返回一个合法的React组件
  3. 由于页面之间跳转,可能会带一些参数,重写hookRoute方法,可以实现更精细的路由控制

3. 代码演示

3.1 在两个页面之间跳转

首先定义好一个路由配置,然后写一个组件继承自NavigatorLayout
import React from 'react'
import { StyleSheet } from 'react-native'
import { NavigatorLayout } from 'tuya-panel-kit'
import Page from './page'
import Home from './home'

const routers = [
  {
    id: 'page1',
    title: 'page1',
    Scene: props => 
  },
  {
    id: 'page2',
    title: 'page2',
    Scene: props => 
  }
]

export default class MainLayout extends NavigatorLayout {
  // eslint-disable-next-line
  hookRoute(route) {
    const theRoute = routers.find(r => r.id === route.id)
    return {
      ...route,
      topbarStyle: { backgroundColor: '#ff6024' },
      showOfflineView: false,
      title: route.id === 'main' ? 'Basic Jump Usage' : theRoute.title
    }
  }

  renderScene(route, navigator) {
    let Scene = 

    const router = routers.find(r => r.id === route.id)
    if (router && router.Scene) {
      const Component = router.Scene
      Scene = 
    }

    return Scene
  }
}
这里我们定义了 2 个页面的路由表(routers), 分别是page1page2, 在renderScene方法里我们可以拿到Naviagtor, 以及当前路由对象的情况,然后我们在渲染页面的时候, 根据当前路由的 id 去路由表查找相应的页面,如果没有对应的页面,我们就渲染默认的主页。
下面是pagehome的实现
// page.js
import React from 'react'
import { View, Text, StyleSheet } from 'react-native'
import { Button } from 'tuya-panel-kit'

// eslint-disable-next-line
export default ({ num, navigator }) => (
  
    This is Page {num}
    
  
)
// home.js
import React from 'react'
import { View, StyleSheet, Text } from 'react-native'
import { Button } from 'tuya-panel-kit'

// eslint-disable-next-line
export default ({ navigator }) => (
  
    
      Welcome to basic usage of NavigatorLayout
    
    {[1, 2].map(v => (
      
    ))}
  
)
通过Navigatorpush方法,我们能跳转到某个页面,通过pop方法,能回退一个页面。 在工程目录下运行yarn start, 并且在 app 输入相应的调试地址,之后我们就可以在 app 上看到效果了。
代码对应的 demo 可以在 github 上找到, 地址: NavigatorLayout 基础使用

3.2 自定义过渡动画效果

NavigatorLayout使用了默认的页面过渡动画配置,即
const SceneConfigs = {
  ...Navigator.SceneConfigs.HorizontalSwipeJump,
  gestures: {
    pop: {
      ...Navigator.SceneConfigs.FloatFromRight.gestures.pop
    }
  }
}
体现出的行为将会是: 平台有关的水平滑动页面跳转, 以及从右到左的页面回退.
使用 3.1 的例子,修改下navigator.push传入的参数,即可自定义过渡动画
import React from 'react'
import { View, StyleSheet, Text } from 'react-native'
import { Button } from 'tuya-panel-kit'
import { Navigator } from 'react-native-deprecated-custom-components'

const sceneConfig = {
  ...Navigator.SceneConfigs.HorizontalSwipeJump,
  gestures: {
    pop: {
      ...Navigator.SceneConfigs.FloatFromRight.gestures.pop
    }
  }
}

const RouterConfig = [
  {
    txt: \`VerticalUpSwipeJump to page 1\`,
    transition: {
      ...sceneConfig,
      ...Navigator.SceneConfigs.VerticalUpSwipeJump
    }
  },
  {
    txt: \`SwipeFromLeft to page 2\`,
    transition: {
      ...sceneConfig,
      ...Navigator.SceneConfigs.SwipeFromLeft
    }
  }
]

// eslint-disable-next-line
export default ({ navigator }) => (
  
    Screen Transition Example!
    {[1, 2].map(v => (
      
    ))}
  
)
这里我们使用了效果VerticalUpSwipeJumpSwipeFromLeft, 以下是效果图
用户可以参考React Native Navigator 过渡动画来使用自己的过渡动画, 比如我们修改下主页的hookRoute

4. 应用

NavigatorLayout是涂鸦面板应用的基石,基本所有面板都用到了它。

5. 函数 API

route: 一个普通对象,里面放着用于渲染的参数,这些参数可以被自定义组件获取到用于渲染。一般 route 会至少带以下参数
id: 当前页面的 id title: 当前页面的在TopBar里显示的标题 topbarStyle: 当前页面的TopBar的样式,是一个 js 对象, 值是React NativeStyleSheet允许的值。 background: 用于渲染页面背景, 可以是一个图片或者渐变 backgroundColor: 背景色,只能是合法的ReactNative颜色值字符串 style: FullView背景样式 hideFullView: true或者false, 表示隐藏 FullView, 一般用于自定义FullView renderFullView: 一个渲染函数,一般配合hideFullView一起使用, 允许用户自己渲染FullView hideTopBar: 是否隐藏TopBar OfflineView: 离线图组件,用于自定义离线图, 需要是一个合法的 React 组件 showOfflineView: 控制是否隐藏离线图, 一般开发调试的时候,会置为false navigator: 即React Native提供的 Navigator, navigator 的 api 可以在这里看到: Navigator 的函数

hookRoute(route) 修改 route 参数

hookRoute(route) 修改 route 参数

由于 route 对象放着用于渲染的参数,开发者会经常修改,为方便开发, 提供 hookRoute 函数用于修改 route 对象的值, route 对象的属性和 renderScene 里的 route 是一致的,用户可以自行往里面放自定义参数, route 只是一个普通对象.

onBack() 返回回调

返回行为一般是指按下安卓返回键, 或者iOS 从左至右滑动的行为, 通常结果是返回上一页. onBack函数就是用于定制返回行为,如果返回 false, 那么将不会返回上一页, 注意,直接调用navigator的 api 还是可以操作页面切换的。

6. PropTypes 传入属性定义

此处是原始的devInfo定义,如果使用涂鸦提供的模板,其中的devInfo经过了特殊的处理以便开发者使用
devInfo: 一个普通 js 对象,包含大量设备的信息, 至少会提供以下字段:

NavigatorLayout 导航布局