NavigatorLayout导航布局

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 => <Page {...props} num={1} />,
}, {
id: 'page2',
title: 'page2',
Scene: props => <Page {...props} num={2} />,
}];

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 = <Home navigator={navigator} />;

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

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 }) => (
<View style={[styles.container, styles.center]}>
<Text style={styles.welcomeTxt}>This is Page {num}</Text>
<Button
style={styles.btnStyle}
onPress={() => navigator.pop()}
>
<Text style={styles.navTxt}>Click to go back!</Text>
</Button>
</View>
);
// 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 }) => (
<View style={[styles.container, styles.center]}>
<Text style={styles.welcomeTxt}>Welcome to basic usage of NavigatorLayout</Text>
{
[1, 2].map(v => (
<Button
style={styles.btnStyle}
key={v}
onPress={() => navigator.push({ id: `page${v}` })}
><Text style={styles.navTxt}>Go to page {v}</Text>
</Button>
))
}
</View>
);

通过Navigatorpush方法,我们能跳转到某个页面,通过pop方法,能回退一个页面。 在工程目录下运行yarn start, 并且在app输入相应的调试地址,之后我们就可以在app上看到效果了。

代码对应的demo可以在github上找到, 地址: NavigatorLayout基础使用

效果图.gif

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 }) => (
<View style={[styles.container, styles.center]}>
<Text style={styles.welcomeTxt}>
Screen Transition Example!
</Text>
{
[1, 2].map(v => (
<Button
style={styles.btnStyle}
key={v}
onPress={() => navigator.push({
id: `page${v}`,
sceneConfigs: RouterConfig[v - 1].transition,
})}
><Text style={styles.navTxt}>{RouterConfig[v - 1].txt}</Text>
</Button>
))
}
</View>
);

这里我们使用了效果VerticalUpSwipeJumpSwipeFromLeft, 以下是效果图 过渡动画效果

用户可以参考React Native Navigator过渡动画来使用自己的过渡动画, 比如我们修改下主页的hookRoute,

4. 应用

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

5. 函数API

renderScene(route, navigator) 渲染页面组件

  • 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的函数

用户需要根据route对象的值来决定渲染哪个子页面,renderScene的返回值必须是一个合法的React组件, 将会用于渲染当前路由页面。

hookRoute(route) 修改route参数

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

onBack() 返回回调

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

6. PropTypes 传入属性定义

此处是原始的devInfo定义,如果使用涂鸦提供的模板,其中的devInfo经过了特殊的处理以便开发者使用

  • devInfo: 一个普通js对象,包含大量设备的信息, 至少会提供以下字段:
    • name: 设备名称
    • productId: 产品id
    • uiId: 当前产品对应的面板id
    • bv: 硬件基线版本
    • devId: 设备Id
    • gwId: 网关Id, 如果是单品,devId一般和gwId相等
    • ability: 只有蓝牙设备使用, 如果是单点蓝牙设备,值是5
    • isOnline: 总判断是否在线
    • isLocalOnline: 局域网是否在线
    • isShare: 是否共享设备
    • isVDevice: 是否是演示设备
    • networkType: 设备的在线类型
    • capability: 设备的能力类型, 标志设备支持什么能力, 如支持zigbee, 红外, 蓝牙等
    • schema: 设备所属产品的功能点(dp, data point)定义, 功能点解释请看dp解释

电话咨询

在线咨询

400-881-8611