UI定制

  SuperMap iTablet定制分为原生和JavaScript两部分。

  原生包含App图标和启动页,需要在App编译前改动;JavaScript部分包含App内部界面与功能的定制,由iTalbet/configs/config.json文件配置。

环境搭建

搭建React Native环境

  搭建React Naïve环境,参考https://reactnative.cn/docs/getting-started/。

  react-native: v0.57.4。

  node: 不高于v12.10.0。

  若首次拷贝项目,需要备份nodemodules,然后npm install后,把nodemodules重新拷贝进iTalbet目录下。

调试

(1).iOS版

  AppDelegate.m设置调试IP,摇晃移动设备“-Debug JS Remotely”打开调试。

+(RCTRootView *)loadBunle:(NSDictionary *)launchOptions {
  ...
  if ([fileMgr fileExistsAtPath:jsBundlePath isDirectory:&isDir]) {
    jsCodeLocation = [NSURL URLWithString:jsBundlePath];
  } else {
    #if DEBUG
    // 有线调试
    //[[RCTBundleURLProvider sharedSettings] setJsLocation:@"localhost"];
    //无线调试,保持电脑和移动设备在同一WIFI下,下面为电脑的IP
    [[RCTBundleURLProvider sharedSettings] setJsLocation:@"10.10.65.195"];
    #endif
    jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
  }
  ...
}

(2).Android版

  数据线连接调试

adb reverse tcp:8081 tcp:8081

  输入IP + Port无线调试

adb shell input keyevent 82 - Dev Settings - Debug server host & port for device

  打开调试界面

adb shell input keyevent 82 - Debug JS Remotely

App图标和启动页

  App图标和启动页需要在原生代码中修改。

Android

  图标设置文件:AndroidManifest.xml“MyProject/android/app/src/main/AndroidManifest.xml”。

<application>
  android:icon="App图标文件路径"
</application>

  启动页设置文件:“ /layout/launch_screen.xml”。

iOS

  图标设置文件:Images.xcassets。

  启动页设置文件:launchScreen.storyboard。

配置文件结构

Config文件结构表

表1 Config文件结构表
字段名称 字段解释 字段类型 可选参数 是否必填
name App标题 String
alias App简称,用于内部部分内容 String
version config版本号 String
language 默认语言 String CN, EN
about 关于的配置 Object isShow:boolean,//是否显示
url:String,//关于的html链接
login 登录的方式 Array [“Online”, “iPortal”]
tabModules App Tabs中的界面配置 Array [“Home”,“Friend”,”Find”, “Mine”,Exmaple, ...]
//Example为定制界面
mapModules 地图功能模块的配置 Array [见表2]
infoServer 消息服务 Object “url”: //消息服务下载文件地址
“fileName”://消息服务下载文件名称
若tabsModules包含Friend则是,反之否
mineModules 我的 功能配置 Array {“key”:”IMPORT”},//导入
{“key”:”MY_SERVICE”},//服务
{“key”:”DATA”},//数据
{“key”:”MARK”},//标注
{“key”:”MAP”},//地图
{“key”:”SCENE”},//场景
{“key”:”BASE_MAP”},//底图
{“key”:”SYMBOL”},//符号
{“key”:”TEMPLATE”},//模板
{“key:””MyColor”},//色带

首页模块定制mapModules

表2 首页模块定制mapModules
字段名称 字段解释 字段类型 可选参数 是否必填
key 键值,用于判断类型 String
functionModules 地图右侧功能模块 Array startModule 二维地图 开始
start3DModule 三维地图 开始
addModule 添加
styleModule 风格
toolModule 工具
shareModule 二维分享
share3DModule 三维分享
fly3DModule 三维旅行轨迹
tool3DModule 三维工具
arAIAssistant AI助手
navigationModule 导航
themeModule 专题
collectionModule 采集
editModule 编辑
plotModule 标绘
analysisModule 分析
incrementModule 增量路网
example 示例地图信息 Object {"checkUrl” //检查下载数据信息
"nickname” //检测下载的数据信息
"type” //下载数据的类型
"url" //下载数据的路径
"example": { // 示范数据
EN: { //系统语言关联的数据
name, // 示例数据名称
mapName, // 默认地图名称 },
DEFAULT: [//可为数组或者对象,第一个为默认示范数据
{ name,
mapName,},],
JA: { //可为数组或者对象,第一个为默认示范数据
name,
mapName, },
},
}
tabModules 地图底部Tabs Array // MapTabs.MapView(地图)和 MapTabs.Sence(三维场景)需要在排第一位
// MapTabs
普通地图:
[
MapTabs.MapView, //二维地图界面
MapTabs.LayerManager,//二维图层管理界面
MapTabs.LayerAttribute,//二维属性界面
MapTabs.LayerAttribute, /二维地图设置界面
]
三维地图:
[
MapTabs.Scene, // 场景界面
MapTabs.Layer3D, // 三维图层管理界面
MapTabs.Attribute3D, // 三维属性界面
MapTabs.Settings3D // 三维场景设置界面
]
否(二三维默认包含)
headerButtons 地图导航栏右侧按钮 Array [// 自定义按钮
{
key,
image,
action,
},
// App默认按钮
'audio', 'undo' 'search', 'share'
]
// iTalbet/configs/mapModules/MapExample.js
import { ConstOnline, MapTabs } from '../../src/constants'
import { getThemeAssets } from '../../src/assets'
import { Module } from '../../src/class'
import {
  startModule,
  addModule,
  markModule,
  toolModule,
  shareModule,
} from '../../src/containers/workspace/components/ToolBar/modules'
// import { functionExample } from '../map
'
export default class MapExample extends Module {
  constructor () {
    super({
      key: 'MapExample', // key值唯一
      // 下载的地图示例数据(可选)
     example: { // 数据可为数组或对象,当前语言对应数据是数组是,第一个为默认数据,并提示下载
          DEFAULT: { // 默认数据,若当前语言没有指定示范数据,默认使用DEFAULT
               name: '湖北',
               mapName: 'LandBuild',
          },
          EN: [  // 英文数据名称
               { 
                   name: 'PrecipitationOfUSA',
                   mapName: 'LosAngeles',
              },
              {
                   name: 'LosAngles',
                   mapName: 'LosAngles',
               },
          ],
       },
      // 配置地图右侧工具栏(可选)
      functionModules: [
        startModule,
        addModule,
        markModule,
        toolModule,
        shareModule,
      ],
      // 配置地图底部Tab栏(可选) MapTabs.MapView(地图)和 MapTabs.Sence(三维场景)需要在排第一位
      // tabModules: [MapTabs.MapView, MapTabs.LayerManager, MapTabs.LayerAttribute, MapTabs.MapSetting]
    })
  }
  // 首页模块数据
  getChunk = language => {
    return this.createChunk(language, {
      key: 'MapExample',
      // 根据语言获取地图模块名称
      title: language === 'CN' ? '示例模块' : 'Example',
      // 模块图片
      moduleImage: getThemeAssets().nav.icon_map_theme,
      // 点击时模块高亮图片
      moduleImageTouch: getThemeAssets().nav.icon_map_theme_touch,
      // 默认地图名称
      defaultMapName: GLOBAL.language === 'CN' ? 'LandBuild' : 'PrecipitationOfUSA',
      // 地图默认底图数据
      baseMapSource: {...ConstOnline.Google},
      // 地图默认底图当前显示的地图
      baseMapIndex: 3,
      licenceType: 0x04,
    })
  }
}
// iTalbet/configs/mapModules/index.js
// 入口文件
/** App自带模块 **/
import * as AppModule from '../../src/customModule/mapModules'
/** 自定义模块 **/
// import MapExample from './MapExample'
/** export顺序为首页模块显示顺序 **/
export default [
  AppModule.MapEditConfig,
  AppModule.Map3DConfig,
  AppModule.MapCollectionConfig,
  AppModule.MapARConfig,
  AppModule.MapNavigationConfig,
  // 自定义模块
  // new MapExample,
  AppModule.MapThemeConfig,
  AppModule.MapPlottingConfig,
  AppModule.MapAnalystConfig,
]

首页tabModules定制

// iTablet/configs/tabModules/Example.js
import React, { Component } from 'react'
import { View } from 'react-native'
import { connect } from 'react-redux'
import TabContainer from '../../src/containers/tabs/TabContainer'
import { getThemeAssets } from '../../src/assets'
class Example extends Component {
  props: {
    language: string,     // redux存放中的当前语言
    navigation: Object,   // TabNavigator导航
    device: Object,       // redux存放设备信息
  }
  constructor(props) {
    super(props)
  }
  static getTitle = language => {
    return language === 'CN' ? 'Map Tab示例' : 'Map Tab Example'
  }
  render() {
    // TabContainer为首页Tab的界面容器,具体Props参照Container组件
    return (
      <TabContainer
        ref={ref => (this.container = ref)}
        hideInBackground={false}
        showFullInMap={true}
        headerProps={{ // Header属性,具体参照Header组件
          title: this.getTitle(),
          withoutBack: true,
        }}
        navigation={this.props.navigation}
      >
        <View style={{flex: 1}} />
      </TabContainer>
    )
  }
}
const mapDispatchToProps = {}
const mapStateToProps = state => ({
  device: state.device.toJS().device,
  language: state.setting.toJS().language,
})
// 链接Redux,获取持久化/全局动态数据
const MyExample = connect(
  mapStateToProps,
  mapDispatchToProps,
)(Example)
// 固定格式
export default {
  key: 'Example',
  getTitle: MyExample.getTitle, // 根据系统语言获取Title
  Screen: MyExample, // 自定义Tab界面
  image: getThemeAssets().tabBar.tab_discover, // Tab未点击图片
  selectedImage: getThemeAssets().tabBar.tab_discover_selected,
                                               // Tab高亮图片
}
// iTablet/configs/tabModules/index.js
// 入口文件
/** export顺序为首页Tabs显示顺序, 默认第一个为Home **/
export default [
  AppTabs.Friend,
  AppTabs.Find,
  // Example,
  AppTabs.Mine,
]

地图右侧FunctionToolbar定制

// iTablet/configs/mapFunctionModules/index.js
// 入口文件
import functionExample from './FunctionExample'
// 获取自定义模块
function getModule (type, params = {}) {
  let module = {}
  if (type === 'FunctionExample') {
    module = functionExample()
  }
  return module
}
export default {
  getModule,
}
export {
  functionExample,
}
// iTablet/configs/mapFunctionModules/FUnctionExample/index.js
import ToolbarModule from '../../../src/containers/workspace/components/ToolBar/modules/ToolbarModule'
import { ToolbarType } from '../../../src/constants'
import CustomFunctionModule from '../../../src/class/CustomFunctionModule'
import FunctionData from './FunctionData'
import FunctionAction from './FunctionAction'
class FunctionExample extends CustomFunctionModule {
  constructor (props) {
    super(props)
    this.setTypes(FunctionExampleTypes) // 用于检测Type是否可用,避免与系统自带类型冲突
  }
  getToolbarSize = () => {}
  action = () => {
    // 注册当前模块数据到ToolbarModule中
    this.setModuleData(this.type)
    const params = ToolbarModule.getParams()
    // 获取显示的数据
    const _data = FunctionData.getData(this.type, params)
    // Toolbar 内容弹出框的类型
    const containerType = ToolbarType.table
    // 获取内容弹出框的尺寸,自定义尺寸需要复写getToolbarSize方法
    const data = ToolbarModule.getToolbarSize(containerType, {})
    // 显示全屏
    params.showFullMap && params.showFullMap(true)
    // 弹出Toolbar并设置类型和内容
    params.setToolbarVisible(true, this.type, {
      containerType,
      isFullScreen: true,
      ...data,
      ..._data,
    })
  }
}
export default function () {
  return new FunctionExample({
    type: 'FunctionExample',
    title: '示例',
    size: 'large',
    image: require('../../../src/assets/function/icon_function_start.png'),
    getData: FunctionData.getData, // 当前Function模块获取数据的方法
    actions: FunctionAction, // 当前Function模块所有事件
  })
}
/**
 * 地图右侧功能基础类
 */
import ToolbarModule from '../containers/workspace/components/ToolBar/modules/ToolbarModule'
export default class FunctionModule {
  constructor(props) {
    this.props = props || {}
    this.type = this.props.type // 类型
    this.key = this.props.title
    this.title = this.props.title || '' // 图标下的文字
    this.size = this.props.size // large | normal(默认) 显示的图标大小
    this.image = this.props.image // 图标
    // 模块相关数据
    this.getData = this.props.getData
    this.getMenuData = this.props.getMenuData
    // 整合默认事件和自定义事件
    this.actions = Object(this.props.actions || {}, Actions)
  }
  /**
   * 自定义高度
   * @param type
   * @param orientation 横竖屏方向
   * @param additional  补充数据,自行定义
   */
  getToolbarSize = (type, orientation, additional) => {
    // let height = 0,
    //   column = -1,
    //   row = -1
    // return { height, column, row }
  }
  /**
   * 存放当前数据到ToolbarModule
   * @param type
   */
  setModuleData = (type = this.type) => {
    ToolbarModule.setData({
      type,
      getData: this.getData,
      actions: this.actions,
      getToolbarSize: this.getToolbarSize,
    })
  }
  /**
   * 启动模块事件
   * @param type
   */
  action = type => {
    this.setModuleData(type)
    this.props.action && this.props.action()
  }
  /**
   * 添加模块事件
   * @param _actions
   */
   addActions = (_actions = {}) => {
    this.actions = Object(this.actions || {}, _actions)
  }
}
/** 模块相关默认事件 **/
const Actions = {
  /********** ToolbarBottomButtons事件 **********/
  commit: () => {},           // 提交
  menu: () => {},             // 屏幕中间的指滑菜单
  showMenuBox: () => {},      // 指滑菜单和内容框交替显示
  showAttribute: () => {},    // 显示属性
  undo: () => {},             // 地图撤销
  redo: () => {},             // 地图重做
  close: () => {},            // 关闭Toolbar
  toolbarBack: () => {},      // Toolbar界面回退
  /********** ToolbarContentView事件 **********/
  listSelectableAction: () => {}, // Toolbar SelectList类型点击事件
  listAction: () => {},           // Toolbar List类型点击事件
  /********** 地图事件 **********/
  geometrySelected: () => {},     // 地图对象选择事件
}

常用组件

  常用组件引用路径 import { 组件 } from ‘src/component’ // src/component改为对应的相对路径。

Container

  界面容器,自带Header导航栏。

// 属性
props: {
  style?: StyleSheet,            // 自定义内容样式
  children: any,                 // Component自带属性,子组件
  header?: any,                  // 自定义导航栏
  bottomBar?: any,               // 自定义底部栏
  withoutHeader?: boolean,       // 设置没有导航栏
  headerProps?: Object,          // 导航栏属性(参照Header.js)
  bottomProps?: Object,          // {type: 'fix'} 底部栏和内容是同一级的,若不是fix,则底部栏是压盖在内容上的
  navigation: Object,            // react-navigation的导航
  initWithLoading?: boolean,     // 初始化显示加载
  dialogInfo?: boolean,          // 加载的文字
  scrollable?: boolean,          // 内容是ScrollView或者View
  showFullInMap?: boolean,       // 横屏时,地图上层界面是否显示半屏
  blankOpacity?: Number,         // 横屏时,半屏遮罩透明度
  hideInBackground?: boolean,    // 在mapview和map3d中,StackNavigator中有新页面时是否隐藏本页面
  orientation?: String,          // redux中的实时横竖屏数据
  onOverlayPress?: () => {},     // 横屏时,半屏遮罩点击事件
  isOverlayBefore?: boolean,     // 横屏是,遮罩的位置,true为左,反之为右
}
// 默认属性
static defaultProps = {
  orientation:
    Dimensions.get('screen').height > Dimensions.get('screen').width
      ? 'PORTRAIT'
      : 'LANDSCAPE',
  withoutHeader: false,
  sideMenu: false,
  initWithLoading: false,
  scrollable: false,
  showFullInMap: false, //是否在mapview和map3d中显示全屏页面,默认半屏
  blankOpacity: 0, //透明半屏的透明度
  hideInBackground: true, //在mapview和map3d中,StackNavigator中有新页面时是否隐藏本页面
  isOverlayBefore: true,
}

  导航栏。

// 属性
props: {
  header?: any,                      // 自定义Header
  headerStyle?: StyleSheet,          // 自定义Header Style
  withoutBack?: boolean,             // 是否有返回按钮
  backBtnType?: string,              // 返回按钮类型(white, gray)
  backAction?: any,                  // 返回事件
  title?: string,                    // 标题
  subTitle?: string,                 // 副标题
  subTitleStyle?: StyleSheet,        // 副标题样式
  headerViewStyle?: StyleSheet,      // Header Style
  headerLeftStyle?: StyleSheet,      // Header左边View样式
  headerRightStyle?: StyleSheet,     // Header右边View样式
  headerTitleViewStyle?: StyleSheet, // Header中间Title View样式
  headerTitleStyle?: StyleSheet,     // Header标题样式
  headerLeft?: any,                  // Header左端组件,可为Array
  headerRight?: any,                 // Header右端组件,可为Array
  opacity?: number,                  // 透明度
  activeOpacity?: number,            // 返回键点击透明度
  type?: string,                     // default | float:浮动Header | floatNoTitle:浮动无title,透明背景 | fix:固定顶部,绝对定位
  navigation?: any,                  // navigation
  count?: any,                       // 消息提示数量
  darkBackBtn?: boolean,             // 黑色透明背景,返回按钮
  headerCenter?: any,                // 自定义Header中间View
  backImg?: any,                     // 返回按钮图片
  statusVisible?: boolean,           // 状态栏是否可见
}
// 默认属性
static defaultProps = {
  title: '',
  withoutBack: false,
  backBtnType: 'gray',
  opacity: 1,
  activeOpacity: 0.2,
  type: 'default',
  headerViewStyle: styles.navigationHeader,
  headerLeftStyle: styles.headerLeftView,
  headerTitleViewStyle: styles.headerTitleView,
  headerTitleStyle: styles.headerTitle,
  subTitleStyle: styles.subTitle,
  count: 0,
  darkBackBtn: false,
  headerCenter: null,
}

BubblePane

  气泡提示框,点击则消失。

<BubblePane ref={ref => (GLOBAL.bubblePane = ref)} maxSize={1} />
// 属性
props: {
  maxSize?: number, // 最大显示气泡消息个数,默认3
}
/**
 * 添加气泡提示
 * @param bubble 气泡数据
 *  { title, type }
 * @param position Pane位置
 *  {top, bottom, left, right}
 */
GLOBAL.bubblePane.addBubble(bubble = {}, position)
/** 清除气泡提示 **/
GLOBAL.bubblePane.clear({})
/** 清空并重置位置 **/
GLOBAL.bubblePane.reset({})

  搜索框。

UI 1
搜索框示例
// 属性
props: {
  onBlur?: () => {},           // 失去焦点事件
  onFocus?: () => {},          // 获得焦点事件
  onClear?: () => {},          // 清除文字
  onSubmitEditing?: () => {},  // 提交
  defaultValue: string,        // 默认值
  editable: string,            // 是否可编辑
  placeholder: string,         // 占位符
  isFocused?: string,          // 是否获得焦点
  keyboardAppearance?: string, // 键盘样式
  returnKeyType?: string,      // Android上确定按钮文字
  returnKeyLabel?: string,     // 键盘返回按钮文字
  blurOnSubmit?: string,       // 是否提交失去焦点
}
// 默认属性
static defaultProps = {
  isFocused: false,
  keyboardAppearance: 'default',
  returnKeyType: 'search',
  returnKeyLabel: '搜索',
  blurOnSubmit: true,
}
<SearchBar
  ref={ref => (this.searchBar = ref)}
  defaultValue={this.state.defaultValue}
  onSubmitEditing={async searchKey => {}}
  placeholder={'请输入搜索关键字'}
/>

MTBtn

  图片按钮,可搭配文字。

UI 2
MTBtn示例
// 属性
props: {
  image: any,                 // 未点击时图片
  selectedImage?: any,        // 点击时图片
  size?: string,              // 图片文字大小
  title?: string,             // 文字
  onPress: () => {},          // 点击事件
  textStyle?: any,            // 自定义文字样式
  textColor?: string,         // 自定义文字颜色
  imageStyle?: any,           // 自定义图片样式
  style?: any,                // 自定义按钮样式
  selected?: boolean,         // 是否被选中
  selectMode?: string,        // normal: 选择 | 非选择状态 // flash:按下和松开
  activeOpacity?: number,     // 点击按钮透明度 0 - 1
  separator?: number,         // 图片和文字的间距
  onPressIn?: () => {},       // 按下时的事件
  onPressOut?: () => {},      // 松开时的事件
}
// 默认属性
static defaultProps = {
  activeOpacity: 1,
  size: 'normal',
  selected: false,
  selectMode: 'normal',
}
// Size的类型
MTBtn.Size = {
  LARGE: 'large',
  NORMAL: 'normal',
  SMALL: 'small',
}
// 示例
<MTBtn
  key={'undo'}
title={getLanguage(this.props.language).Map_Attribute.ATTRIBUTE_UNDO}
  style={styles.button}
  textColor={!this.state.canBeUndo && color.contentColorGray}
  image={
    this.state.canBeUndo
      ? getThemeAssets().publicAssets.icon_undo
      : getPublicAssets().attribute.icon_undo_disable
  }
  imageStyle={styles.headerBtn}
  onPress={() => this.setAttributeHistory('undo')}
/>

Input

  输入框,当有值时,显示清除按钮。

UI 3
输入框示例
// 属性,参照React Native TextInput
props: {
  accessible?: boolean,
  accessibilityLabel?: string,
  showClear?: boolean,           // 显示清除按钮
  isKeyboardAvoiding?: boolean,  // 是否使用KeyboardAvoidingView键盘
  behavior?: string,             // ReactNative KeyboardAvoidingView
  style?: Object,                // Input样式
  inputStyle?: Object,           // 自定义输入框样式
  placeholder?: string,          // 占位符
  value?: string,                // 输入框值
  defaultValue?: string,         // 输入框默认值
  keyboardAppearance?: string,   // 键盘颜色
  returnKeyType?: string,        // 返回键类型
  placeholderTextColor?: string, // 占位符颜色
  keyboardType?: string,         // 弹出键盘类型
  textContentType?: string,      // iOS输入内容类型,eg:password
  secureTextEntry?: boolean,     // 密码
  onChangeText?: () => {},       // 输入回调
  onClear?: () => {},            // 自定义清除事件
}
static defaultProps = {
  label: '',
  keyboardAppearance: 'dark',
  returnKeyType: 'done',
  keyboardType: 'default',
  placeholder: '',
  placeholderTextColor: color.themePlaceHolder,
  showClear: false,
  isKeyboardAvoiding: false,
  secureTextEntry: false,
}

Row

  多类型行,文本+(输入框,单选框,数字,文字按钮)。

UI 4
多类型行示例
props: {
  style?: Object,                  // 自定义Row样式
  titleStyle?: Object,             // 左侧文字样式
  customRightStyle?: Object,       // 右侧内容样式
  title: string,                   // 左侧文字
  defaultValue?: any,              // 默认值
  customRightView?: any,           // 自定义右侧内容
  type?: string,                   // Row.Type
  inputType?: string,              // Row.InputType
  value?: any,                     // 值
  radioArr?: Array,                // 单选框组[{title, value}]
  radioColumn?: number,            // 单选框组列数
  separatorHeight?: number,        // 单选框行间隔
  minValue?: number,               // CHOOSE_NUMBER 最小值
  maxValue?: number,               // CHOOSE_NUMBER 最大值
  commonDifference?: number,       // CHOOSE_NUMBER 公差,值之间差值
  times?: number,                  // CHOOSE_NUMBER 倍数
  unit?: string,                   // CHOOSE_NUMBER 单位
  getValue?: () => {},             // 获取值的回调
  disable?: boolean,               // 是否可操作
}
Row.Type = {
  INPUT: 'input',                  // 普通输入框
  INPUT_WRAP: 'input_wrap',        // 含删除输入框Input
  RADIO: 'radio',                  // 一个单选框
  RADIO_GROUP: 'radio_group',      // 多个单选框
  CHOOSE_NUMBER: 'choose_number',  // 含数字增减按钮
  CHOOSE_COLOR: 'choose_color',    // 色板
  TEXT_BTN: 'text_btn',            // 文字按钮
}
// 输入框内容,键盘类型
Row.InputType = {
  NUMERIC: 'numeric', // 数字键盘
  DEFAULT: 'default', // 默认
}
// 示例
<Row
  style={{ marginTop: scaleSize(30) }}
  customRightStyle={styles.customRightStyle}
  key={'名称'}
  disable={this.state.isEdit}
  defaultValue={this.state.name}
  type={Row.Type.INPUT_WRAP}
  title={getLanguage(global.language).Map_Attribute.NAME}
  getValue={this.getInputValue}
/>
<Row
  style={{ marginTop: scaleSize(15) }}
  customRightStyle={styles.customRightStyle}
  key={'别名'}
  disable={this.state.isEdit}
  defaultValue={this.state.caption}
  type={Row.Type.INPUT_WRAP}
  title={getLanguage(global.language).Map_Attribute.ALIAS}
  getValue={this.getInputValue}
/>
<Row
  style={{ marginTop: scaleSize(30) }}
  key={'类型'}
  type={Row.Type.RADIO_GROUP}
  title={getLanguage(global.language).Map_Attribute.TYPE}
  defaultValue={this.state.type}
  disable={this.state.isEdit}
  customRightView={
    <TouchableOpacity
      style={{
        flexDirection: 'row',
        justifyContent: 'space-between',
        alignItems: 'center',
      }}
      onPress={
        this.state.isEdit
          ? null
          : () => {
            Keyboard.dismiss()
            this.popModal && this.popModal.setVisible(true)
          }
      }
    >
      <Text style={{ fontSize: scaleSize(24), color: color.gray }}>
        {this.state.currentPopData
          ? this.state.currentPopData.key
          : null}
      </Text>
      <Image
        source={require('../../../../assets/Mine/mine_my_arrow.png')}
        style={{ height: scaleSize(28), width: scaleSize(28) }}
      />
    </TouchableOpacity>
  }
/>
<Row
  style={{ marginTop: scaleSize(15) }}
  key={'必填'}
  type={Row.Type.RADIO_GROUP}
  title={getLanguage(global.language).Map_Attribute.REQUIRED}
  disable={this.state.isEdit}
  defaultValue={this.state.isRequired}
  radioArr={[
    { title: getLanguage(global.language).Prompt.YES, value: true },
    { title: getLanguage(global.language).Prompt.NO, value: false },
  ]}
  radioColumn={2}
  getValue={this.getType}
/>

SurfaceView

  画板(eg:圆选裁剪,框选裁剪),并获取点位置。

UI 5
画板示例
props: {
  style: Object,
  type: string,        // ShapeType
  orientation: string, // 横竖屏
}
// 显隐SurfaceView
show = isShow => {
    // ...
}
// 获取点位置
getResult = () => {
  switch (this.props.type) {
    case ShapeType.CIRCLE:
      return [this.state.startPoint, this.state.endPoint]
    case ShapeType.RECTANGLE:
    default:
      return [
        this.state.startPoint,
        { x: this.state.startPoint.x, y: this.state.endPoint.y },
        this.state.endPoint,
        { x: this.state.endPoint.x, y: this.state.startPoint.y },
      ]
  }
}
const ShapeType = {
  RECTANGLE: 'RECTANGLE',
  CIRCLE: 'CIRCLE',
}

TableList

  表格列表。Table类型根据orientation限制行或列,PORTRAIT时列固定,行自适应;LANDSCAPE时行固定,列自适应。scrollTable类型始终固定列数。

UI 6
表格列表示例
props: {
  data: Array,               // 数据
  lineSeparator?: number,    // 行间距
  style?: Object,            // 表格样式
  cellStyle?: Object,        // Cell样式
  rowStyle?: Object,         // 行样式
  renderCell: () => {},      // 自定义Cell, 必填
  type?: string,             // normal 固定 | scroll 滚动
  device?: string,           // 设备信息
  isAutoType?: Boolean,      // 是否根据个数,自适应滚动或固定表格
  column?: number,           // 列数
  numberOfRows?: number,     // 行数限制
}
static defaultProps = {
  data: [],
  column: 2,
  numberOfRows: 6,
  type: 'table', // normal | scroll
  lineSeparator: 5,
  isAutoType: true,
}
// 示例
_renderItem = ({ item, rowIndex, cellIndex }) => {
  return (
    <MTBtn
      key={rowIndex + '-' + cellIndex}
      title={item.title}
      textColor={item.disable ? '#A0A0A0' : color.font_color_white}
      textStyle={{ fontSize: setSpText(20) }}
      image={item.image}
      background={item.background}
      onPress={() => {
        !item.disable && this.itemAction(item)
      }}
    />
  )
}
<TableList
  data={this.props.data}
  column={this.props.column}
  numberOfRows={this.props.row}
  type={this.props.containerType}
  renderCell={this._renderItem}
  device={this.props.device}
/>

Progress / PieProgress

  条形/圆形进度条。

UI 7
进度条示例
static propTypes = {  ...View.propTypes,
  //当前进度
  progress?: PropTypes.number,
  //second progress进度
  buffer?: PropTypes.number,
  //进度条颜色
  progressColor?: PropTypes.string,
  //buffer进度条颜色
  bufferColor?: PropTypes.string,
  //进度动画时长
  progressAniDuration?: PropTypes.number,
  //buffer动画时长
  bufferAniDuration?: PropTypes.number,
}
static defaultProps = {
  //进度条颜色
  progressColor: 'yellow',
  //buffer进度条颜色
  bufferColor: 'rgba(255,0,0,0.7)',
  //进度条动画时长
  progressAniDuration: 300,
  //buffer进度条动画时长
  bufferAniDuration: 300,
}

CheckBox

  复选框。

UI 8
复选框示例
props: {
  onChange: () => {}, // 选中/取消的回调
  style?: Object,
  imgStyle?: Object,
  disable?: boolean,
  checked?: boolean,
}
static defaultProps = {
  disable: false,
}

  界面中间指滑菜单:触摸屏幕,白色框体上下滑动,松手或者点击菜单选项,为选中操作。触摸范围:父类组件全屏。

UI 9
界面中间指划菜单示例
// MenuDialog属性
props: {
  data: Array,                 // 数据
  selectKey?: '',              // 当前选中的key
  viewableItems?: number,      // 可见范围item的数量,默认为3
  autoSelect?: boolean,        // 松手自动选择
  onSelect?: () => {},         // 选中item的回调
  device: Object,              // 设备信息
}
// MenuDialog使用方法
<MenuDialog
  data={this.state.data}
  selectKey={this.props.selectKey}
  autoSelect={true}
  device={this.props.device}
  onSelect={item => {
    this.setState({
      selectKey: item.selectKey,
      selectName: item.selectName || item.key,
    })
  }}
/>
// MenuDialog数据格式
data = [
  {
    key: 'test',
    action: () => {},  // 点击事件
    selectKey: 'test', // 菜单Item文字
  },
]

FingerMenu

  固定的指滑菜单,上下滚动菜单,中间蓝色部分为选中项。

UI 10
固定指划菜单示例
// 属性
props: {
  data: Array,             // 数据[{ key 显示Title, icon 图标, highLightIcon 选中的图标 }]
  initialKey: string,      // 初始数据
  selectKey?: '',          // 当前选中的key
  viewableItems?: number,  // 可见范围item的数量,单数
  autoSelect?: boolean,    // 松手自动选择
  onSelect?: () => {},     // 选中item的回调
  onScroll?: () => {},     // 滚动选中item的回调
  onScrollEnd?: () => {},  // 滚动结束的回调
  onDragEnd?: () => {},    // 手指拖动结束的回调
  rowHeight?: number,      // 行高
  style?: Object,
}
static defaultProps = {
  data: [],
  initialKey: '',
  viewableItems: 5,
  rowHeight: ITEM_HEIGHT,
}
// 示例
<FingerMenu
  ref={ref => (this.fingerMenu = ref)}
  data={this.props.popData}
  initialKey={
    (this.props.currentPopData && this.props.currentPopData.key) ||
    (this.props.popData.length > 0 && this.props.popData[0].key)
  }
/>
// 数据格式
data = [
  {
    key: 'test',
    icon: 图标,
    highLightIcon: 选中的图标,
  },
]

PopModalList

  底部弹出列表。

  finger类型:对FingerMenu封装,多了“取消”、“确定”两个按钮。

UI 11
底部弹出列表示例

  mutil类型:多选列表。

UI 12
底部弹出多选列表示例
const LIST_TYPE = {
  FINGER: 'finger', // 指滑单选列表
  MULTI: 'multi', // 复选框多选列表
}
props: {
  language?: String,        // 语言,用于根据当前语言设置按钮Title
  type?: String,            // LIST_TYPE
  confirm: () => {},        // 自定义确定事件
  cancel: () => {},         // 自定义取消事件
  confirmTitle?: String,    // 自定义确定Title
  cancelTitle?: String,     // 自定义取消Title
  popData: Array,           // 数据[{ key 显示Title, icon 图标, highLightIcon 选中的图标 }]
  currentPopData: Object,   // 当前选中对象,用户初始化选中对象
}

static defaultProps = {
  type: LIST_TYPE.FINGER, // finger, multi
}
// 示例
<PopModalList
  ref={ref => (this.popModal = ref)}
  language={this.props.language}
  popData={this.state.popData}
  currentPopData={this.state.currentPopData}
  confirm={data => {}}
/>
data = [
  {
    key: 'test',
    icon: 图标,
    highLightIcon: 选中的图标,
  },
]

LinkageList

  二级联动菜单,支持改变左右列表宽度。

UI 13
二级联动菜单
props: {
  language: String,
  data: Array, // 菜单数据
  titles: Array, //左右侧标题
  onLeftPress?: () => {}, //左侧点击
  onRightPress?: () => {}, //右侧点击
  styles?: Object, //样式
  adjustmentWidth?: boolean,
  isMultiple: boolean, //是否是多选
}
static defaultProps = {
  adjustmentWidth: false,
}
// 数据格式
data = [
  {
    title: alias,
    server: udbPath,
    engineType: EngineType.UDB,
    data: [{title: '111', parentTitle: alias}], // 右侧列表数据
  },
]
// 示例
<LinkageList
  ref={ref => (this.linkageList = ref)}
  language={this.props.language}
  adjustmentWidth={true}
  data={this.props.userUdbAndDs}
  titles={[
    getLanguage(this.props.language).Analyst_Labels.DATA_SOURCE,
    getLanguage(this.props.language).Analyst_Labels.DATA_SET,
  ]}
  onRightPress={this.listRightAction}
/>

MediaPager

  多媒体浏览组件,支持视频和图片翻页阅览。

props: {
  data: Array,
  isModal: boolean,        // 是否使用Model作为容器
  withBackBtn: boolean,    // 左上角是否有返回按钮
  backHide?: boolean,      // 
  defaultIndex: number,
}
static defaultProps = {
  isModal: false,
  withBackBtn: false,
  defaultIndex: 0,
  data: [],
  backHide: true,
}
// 数据格式
data = [
  {uri: ''} // 根据uri后缀区分视频还是图片
]
<MediaPager
  ref={ref => (this.mediaViewer = ref)}
  data={this.state.paths}
  withBackBtn
  isModal
/>
// 显示隐藏MediaPager,index为默认显示第几个
setVisible = (visible = !this.state.visible, index = 0)