关于reactnative:tarorn开发scrollview不能嵌套flatlist

报错VirtualizedLists should never be nested inside plain ScrollViews.... 背景:开发一个swipecell左滑删除的组件,应用了一个第三方库:react-native-swipe-list-view 该库基于reactnative的flatlist实现。 问题呈现:问题呈现了,吭哧吭哧地接入这个包的时候发现页面报了个谬误 :VirtualizedLists should never be nested inside plain ScrollViews.... 报错剖析:嗯哼?连忙去搜一把这是啥。Virtualized Lists也就是咱们常说的虚构列表,虚构列表只让可视区域范畴内的 Cell 渲染,超出可视区域范畴内的 Cell 销毁来缩小渲染带来的内存开销问题。而FlatList 和 SectionList 都是用的 Virtualized Lists。当咱们把 Virtualized List 放在 ScrollView 中,ScrollView 是要全副渲染的,那么 Virtualized List 无奈计算出以后哪些 Cell 是展现在可视区域范畴内而会抉择渲染所有的 Cell,so ! Virtualized Lists的劣势就浮现不进去了。这个时候就会抛出上述正告。o(╥﹏╥)o 查找起因:上述解释艰深地说就是flatlist不能嵌套ScrollView!rn页面是默认不滚动的,若想实现页面滚动须要应用scrollview包裹内容。查看了本人的代码没发现加了scrollview,最初的最初总算找到了taro中有disableScroll配置项,disableScroll默认配置了页面滑动(配置在config.ts页面中)也就是说taro外层是有一个scrollview包裹页面于是就导致上述问题产生。下次如果应用taro开发rn利用的时候就要留神这个问题啦! 总结:先入为主会找不到解决的方向哦。完了。溜~

June 16, 2022 · 1 min · jiezi

React-Native-关闭所有黄色警告

console.ignoredYellowBox = [ 'Warning: BackAndroid is deprecated. Please use BackHandler instead.', 'source.uri should not be an empty string', 'Invalid props.style key',];console.disableYellowBox = true; // 关闭全部黄色警告将这两句话加在index.js文件中,放在AppRegistry.registerComponent('App', () => App)之前。

July 6, 2020 · 1 min · jiezi

ReactNavigation-5X的配置

React-Navigation 5.X相比较于之前版本,5.x实现了全部组件化的开发,将原来的包拆分成了许多的组件进行使用,使用方式也发生了很大的变化。 安装通过yarn来安装 yarn add @react-navigation/native还需要安装react-navigation需要的一些包 yarn add react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-viewreact-native-reanimated 是动画库性能很好,使用组件来实现的。react-native-gesture-handler 跨平台的手势库。react-native-screens 实现了Android和ios的screen原生组件。react-native-safe-area-context 适配异性屏幕。@react-native-community/masked-view 堆栈式导航器所依赖的库。 额外操作React Native 0.60 版本以后, 会自动link。因此你不需要执行react-native link。 iOSmac需要执行一下 cd iodpod installcd ..Android来到手势库官网https://docs.swmansion.com/re...这个目录下的文件android\app\src\main\java\com\MainActivity.java添加+后面的内容 package com.swmansion.gesturehandler.react.example;import com.facebook.react.ReactActivity;+ import com.facebook.react.ReactActivityDelegate;+ import com.facebook.react.ReactRootView;+ import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;public class MainActivity extends ReactActivity { @Override protected String getMainComponentName() { return "Example"; }+ @Override+ protected ReactActivityDelegate createReactActivityDelegate() {+ return new ReactActivityDelegate(this, getMainComponentName()) {+ @Override+ protected ReactRootView createRootView() {+ return new RNGestureHandlerEnabledRootView(MainActivity.this);+ }+ };+ }}在index.js引入import 'react-native-gesture-handler';如果忘记了添加这个,开发环境可能不会报错,但是在生产环境会报错。 ...

July 2, 2020 · 1 min · jiezi

ReactNative分布式热更新系统

热更新是一个非常方便的方案。在应对大量用户和深度定制的时候一定不能使用开源的方案。一般第三方的这种方案,服务器带宽较小,或者不够灵活,不能满足自己的想法。这里推荐自己实现对应的热更新方案。只需要少量代码即可支持。下面推荐一种灵活的热更新方案。包括客户端的改造、接口设计、界面开发,同时是开源的!可以自由改造。体验地址:demo 用户名密码都是:admin 基础数据的准备和实现首先第一点,一个APP如果要支持热更新,需要在打开APP(或者其他进入RN页面之前)就要判断是否需要更新bundle文件。这里就是我们实现热更新的节点。一旦需要热更新就开始下载文件,而判断的接口就是我们这次文章的核心内容。这里简单贴出安卓和ios两端的下载逻辑。 请求之前需要在head中附带上客户端的几个重要信息。客户端版本号version、客户端唯一id:clientid、客户端类型platform、客户端品牌brand。ios下载的例子 -(void)doCheckUpdate{ self.upView.viewButtonStart.hidden = YES; if ([XCUploadManager isFileExist:[XCUploadManager bundlePathUrl].path]) {//沙盒里已经有了下载好的jsbundle,以沙盒文件优先 self.oldSign = [FileHash md5HashOfFileAtPath:[XCUploadManager bundlePathUrl].path]; }else {//真机计算出的包内bundlemd5有变化,可能是压缩了,所以这里写死初始化的md5 // NSString *ipPath = [[NSBundle mainBundle] pathForResource:@"main" ofType:@"jsbundle"]; // self.oldSign = [FileHash md5HashOfFileAtPath:ipPath]; self.oldSign = projectBundleMd5; } AFHTTPSessionManager *_sharedClient = [[AFHTTPSessionManager alloc] initWithBaseURL:[NSURL URLWithString:@"http://test.com"]]; [self initAFNetClient:_sharedClient]; [_sharedClient GET:@"api/check" parameters:nil progress:nil success:^(NSURLSessionDataTask * __unused task, id JSON) { NSDictionary *dic = [JSON valueForKeyPath:@"data"]; BOOL isNeedLoadBundle = YES; if ([dic isKindOfClass:[NSDictionary class]]) { self.updateSign = [dic stringForKey:@"sign"]; self.downLoadUrl = [dic stringForKey:@"downloadUrl"]; if(self.updateSign.length && self.oldSign.length && (![self.updateSign isEqualToString:self.oldSign])) { //需要更新bundle文件了 self.upView.viewUpdate.hidden = NO; [self updateBundleNow]; isNeedLoadBundle = NO; }else { //不需要更新bundle文件,再处理跳过按钮显示逻辑 [self.upView showSkipButtonOrNot]; } } if (isNeedLoadBundle) { [self loadBundle]; } } failure:^(NSURLSessionDataTask *__unused task, NSError *error) { [self loadBundle]; }];}安卓下载的例子 ...

August 19, 2019 · 2 min · jiezi

2019年Flutter-和-React-Native-谁主沉浮

Flutter 与 React Native混淆了吗?本文是帮助你了解这两个应用程序开发框架区别指南。咱们知道,几年前开发和维护iOS和Android的应用程序曾经是一项艰巨的任务(独立的代码库|独立的开发团队|开发成本也忒高)。 一堆狗屎。 移动行业渴望进行一场革命,以遏制移动应用程序开发过程中出现的问题。 因此,跨平台开发的形式就此出现了。现在,维护代码和开发应用程序对于开发人员来说变得简单且耗时也少了。 跨平台应用程序开发什么时候出现的?不仅开发商,企业和初创公司也通过为跨平台应用的方式来开发他们的业务。不出所料,他们喜欢它。 为了提高应用开发的效率,越来越多的跨平台应用开发框架应运而生。 脸书在2015年又跳了回来,推出了React native。 毫无疑问,它得到很好的回应。如今,React native 是 Facebook、沃尔玛(Walmart)、优步(UberEats)、Instagram 和特斯拉(Tesla)等应用程序的幕后支持者。 后来,谷歌也加入了进来,并推出了广受好评的跨平台框架 Flutter。并保证了所有应用程序都具有原生性能。 从那时起,新创公司和企业就面临着如何选择应用程序开发的两难境地。这使得 Flutter 与 React native 的争论更加激烈。 在本文中,我们将讨论React Native 和 Google 的 Flutter 之间备受争议的论点。 想阅读更多优质文章请猛戳GitHub博客,一年百来篇优质文章等着你! 什么是 FlutterFlutter 是谷歌的移动UI框架,可以快速在 iOS 和 Android上构建高质量的原生用户界面。 什么是 React NativeReact Native (简称RN)是Facebook于2015年4月开源的跨平台移动应用开发框架,是Facebook早先开源的JS框架 React 在原生移动应用平台的衍生产物,目前支持iOS和安卓两大平台。RN使用Javascript语言,类似于HTML的JSX,以及CSS来开发移动应用,因此熟悉Web前端开发的技术人员只需很少的学习就可以进入移动应用开发领域。 现在你已经有了基本的认识,让咱们来看看在 2019 年的 React nNtive 和 Flutter 中哪个更好? Flutter vs React Native:详细比较让我们详细看看这两个平台之间的差异,并找出使用 React native 和Flutter 的优缺点。 程序设计语言跨平台的应用程序开发框架都使用不同的编程语言。 React native 可以使用 Javascript开发,这不需要任何介绍。长期以来,它一直是开发人员最好的编程语言。 ...

June 13, 2019 · 2 min · jiezi

React-Navigation-导航栏样式调整底部角标消息提示

五一佳节匆匆而过,有人选择在外面看人山人海,有人选择宅在家中度过五一,也有人依然坚守在第一线,致敬! 这是坚持学习react-native的第二篇文章,可能会迟到,但是绝不会缺席,这篇要涉及到的是react-navigation,也是rn社区主推的一个导航库。 网上关于react-navigation的基本使用也是一抓一大把,这里对于它的使用不做过多介绍,主要记录使用过程中的其他问题。 因为android 和iOS 手机的不同,导航栏的显示也不太一样,而这篇文章会尽量的配置属性,让两端的导航栏样式、页面跳转的动画保持一致,同时还会介绍底部导航栏添加角标的方法。 这里使用的是3.9.1版本,网上好多文章是2.x版本的,用法基本大同小异。 android 导航栏标题居中适配默认情况下,iOS的标题居中显示,而android的则不!!! 解决:createStackNavigator的defaultNavigationOptions属性里配置textAlign和flex const AppStackNavigator = createStackNavigator({ HomeScreen: {screen: HomeScreen}, RainScreen: {screen: RainScreen}},{ defaultNavigationOptions:{ ... headerTitleStyle: { ... textAlign: "center", //用于android 机型标题居中显示 flex:1 } }})注:android机型标题默认不居中,textAlign和flex的属性配置用于android机型标题居中显示。 在这种情况下,如果配置了headerLeft或者headerRight 属性,会出现标题偏移的现象。 直接在defaultNavigationOptions里配置空view的headerLeft和headerRight defaultNavigationOptions:{ ... headerTitleStyle: { ... textAlign: "center", //用于android 机型标题居中显示 flex:1, }, headerRight: <View/>, headerLeft: <View/> }这时候标题居中,同时可以在各自的页面里面去重写headerLeft的样式。 android 导航栏去除阴影样式android的导航栏还有阴影的样式,添加elevation 设置阴影的偏移量 defaultNavigationOptions:{ headerStyle:{ backgroundColor:"#fff", elevation:0.5 }, ...}至此的导航栏的效果跟iOS基本保持一致。 android 页面跳转动画,自右向左打开默认的android页面跳转是自下而上打开页面,而要与iOS的保持一致的自右向左,配置transitionConfig属性。 const AppStackNavigator = createStackNavigator({ HomeScreen: {screen: HomeScreen}, ...},{ defaultNavigationOptions:{ ... }, transitionConfig: () => ({ screenInterpolator: (sceneProps) => { return StackViewStyleInterpolator.forHorizontal(sceneProps) }, }),})底部导航添加消息角标有时候我们会遇到这样的需求,在底部导航处添加消息的角标,提醒用户阅读的。 在tabBarIcon的属性里直接添加图标显示的,这里的msg变量数值是全局的,只做演示使用,实际项目里可以根据接口返回数据,可以搭配mobx 一起使用。 ...

May 6, 2019 · 1 min · jiezi

手把手教你如何自定义 React Native 底部导航栏

如果你觉得 React Navigation 默认 Tab 组件看起来太平淡,或者想创造一些更现代的东西,那么你想法就和我一样。 在本指南中,我将向你演示如何创建自定义标签栏以并与 React Navigation 一起使用。源码已发布到 github,如果有需要,请点击这里。这是最终完成的样子:首先,让我们初始化一个新项目并安装几个依赖项。在终端运行如下命令:$ react-native init CustomTabBar$ cd CustomTabBar$ npm install react-navigation react-native-gesture-handler react-native-poseReact Navigation 从 V3 开始需要依赖 react-native-gesture-handler 库,react-native-pose 是一个很棒的库,我们将用它来制作非常简单的动画。react-native-gesture-handler 需要通过 link 命令将一些配置自动关联到原生中。react-native link react-native-gesture-handler现在我们可以启动应用程序了。首先——我们创建如下一个目录结构,方便代码管理:/android/ios…/src /AppEntry.js /router /router.js /index.js /components /screens/index.js首先,我们将创建一个 src 目录,将我们的代码与项目根目录中的其他文件(package.json,app.json,.gitignore 等)分开。 screens,components 和 router 目录是知名其意的。我们从项目的根目录中删除默认的App.js文件,并在 index.js 中写入import /src/AppEntry.js/* /index.js /import { AppRegistry } from “react-native”;import App from “./src/AppEntry”;import { name as appName } from “./app.json”;AppRegistry.registerComponent(appName, () => App);现在我们想要使用 react-navigation 创建路由器,但是首先我们需要创建一些 screen(就是页面)。我们将创建一个通用的 Screen 组件,它接受一个名称并显示它来模拟多个 Screen。在 /src/screens/index.js 添加如下内容:/ /src/screens/index.js /import React from “react"import Screen from “./Screen"export const HomeScreen = () => <Screen name=“Home”/>export const SearchScreen = () => <Screen name=“Search” />export const FavoritesScreen = () => <Screen name=“Favorites” />export const ProfileScreen = () => <Screen name=“Profile” />;现在我们创建 Screen 组件。/ /src/screens/Screen.js /import React from “react”;import { Text, View, StyleSheet } from “react-native”;const S = StyleSheet.create({ container: { flex: 1, backgroundColor: “#bbbbbb”, justifyContent: “center”, alignItems: “center” }, text: { fontSize: 28, color: “#222222”, textAlign: “center” }});const Screen = ({ name }) => ( <View style={S.container}> <Text style={S.text}>This is the “{name}” screen</Text> </View>);export default Screen;接着创建路由,首先在 /src/router/index.js 在添加如下内容:/ /src/router/index.js /export { default as Router } from “./router”;现在让我们在 router.js 中创建基本的 BottomTabNavigator。 我们将导入 screens 并使用createBottomTabNavigator 创建默认选项卡导航器。/ /src/router/router.js /import { createAppContainer, createBottomTabNavigator } from “react-navigation”;import { HomeScreen, SearchScreen, FavoritesScreen, ProfileScreen} from “../screens”;const TabNavigator = createBottomTabNavigator({ HomeScreen, SearchScreen, FavoritesScreen, ProfileScreen});export default createAppContainer(TabNavigator);现在我们在 AppEntry.js 中渲染路由:/ /src/AppEntry.js /import React from “react”;import { Router } from “./router”;export default () => <Router />;当我们重新加载应用程序时,应该会如下内容:默认标签栏支持图标,我们将在本教程中使用 ascii 字符,当然在实际应用中可以使用 react-native-vector-icons 或自定义图标字体。让我们创建一个 Icon 组件,接受参数为 name 和 color 并返回图标。/ /src/components/index.js /export { default as Icon } from “./Icon”;/ /src/components/Icon.js /import React from “react”;import { Text } from “react-native”;const iconMap = { home: “♡”, search: “♢”, favorites: “♧”, profile: “♤”};const Icon = ({ name, color, style, …props }) => { const icon = iconMap[name]; return <Text style={[{ fontSize: 26, color }, style]}>{icon}</Text>;};export default Icon;现在我们可以在路由器中使用这个组件。我们在 router.js 中更改 screens ,以接受带有navigationOptions 配置的对象。默认选项卡栏将 tintColor 传递给图标组件,因此我们使用它来设置图标颜色。/ /src/router/router.js / import { createAppContainer, createBottomTabNavigator } from “react-navigation”;import React from “react”;import { HomeScreen, SearchScreen, FavoritesScreen, ProfileScreen} from “../screens”;import {Icon} from ‘../components’const TabNavigator = createBottomTabNavigator({ HomeScreen: { screen: HomeScreen, navigationOptions: { tabBarIcon: ({ tintColor }) => <Icon name=“home” color={tintColor} /> } }, SearchScreen: { screen: SearchScreen, navigationOptions: { tabBarIcon: ({ tintColor }) => <Icon name=“search” color={tintColor} /> } }, FavoritesScreen: { screen: FavoritesScreen, navigationOptions: { tabBarIcon: ({ tintColor }) => <Icon name=“favorites” color={tintColor} /> } }, ProfileScreen: { screen: ProfileScreen, navigationOptions: { tabBarIcon: ({ tintColor }) => <Icon name=“profile” color={tintColor} /> } }});export default createAppContainer(TabNavigator);运行效果如下:现在我们的标签栏看起来好一点,但它仍然是 react-navigation 的默认标签栏。 接下来,我们将添加实际的自定义标签栏组件。让我们从创建一个自定义 TabBar 组件开始,该组件只渲染一些文本并打印传递过来的 props ,这样我们就可以看到我们从导航器中得到了什么 props。/ /src/components/index.js /export { default as Icon } from “./Icon”;export { default as TabBar } from “./TabBar”;/ /src/components/TabBar.js /import React from “react”;import { Text } from “react-native”;const TabBar = props => { console.log(“Props”, props); return <Text>Custom Tab Bar</Text>;};export default TabBar;使用自定义标签栏需要配置 createBottomTabNavigator 第二个参数, 我们可以添加以下配置作为createBottomTabNavigator 的第二个参数。如果我们查看标签栏打印了什么,我们会看到导航栏中有 navigation.state状态,其中也包含路由。还有 renderIcon 函数,onTabPress 和很多我们可能需要的东西。此外,我们还注意到我们在路由器配置中 tabBarOptions 是如何被注入到组件中的。现在重新编写 TabBar 组件。首先,让我们尝试重新创建默认选项卡栏。我们将在容器上设置一些样式,以便将选项卡按钮排成一行,并为每个路由呈现一个选项卡按钮。我们可以使用 renderIcon 函数来渲染正确的图标——通过查看源代码,该函数需要传入一个对象参数: { route, focused, tintColor }。我们添加了onPress 处理程序、易访问性标签,这样就有了默认的选项卡栏。/ /src/components/TabBar.js /import React from “react”;import { View, Text, StyleSheet, TouchableOpacity } from “react-native”;const S = StyleSheet.create({ container: { flexDirection: “row”, height: 52, elevation: 2 }, tabButton: { flex: 1, justifyContent: “center”, alignItems: “center” }});const TabBar = props => { const { renderIcon, getLabelText, activeTintColor, inactiveTintColor, onTabPress, onTabLongPress, getAccessibilityLabel, navigation } = props; const { routes, index: activeRouteIndex } = navigation.state; return ( <View style={S.container}> {routes.map((route, routeIndex) => { const isRouteActive = routeIndex === activeRouteIndex; const tintColor = isRouteActive ? activeTintColor : inactiveTintColor; return ( <TouchableOpacity key={routeIndex} style={S.tabButton} onPress={() => { onTabPress({ route }); }} onLongPress={() => { onTabLongPress({ route }); }} accessibilityLabel={getAccessibilityLabel({ route })} > {renderIcon({ route, focused: isRouteActive, tintColor })} <Text>{getLabelText({ route })}</Text> </TouchableOpacity> ); })} </View> );};export default TabBar;运行后,效果如下:现在我们知道我们可以灵活地创建自己的标签栏,因此我们可以开始实际扩展它。 我们将使用 react-native-pose 创建一个动画视图,该视图将突出显示活动路径 - 我们将此视图称为聚光灯。首先我们可以去掉标签。然后我们在标签栏后面添加一个绝对视图,它将显示聚光灯效果。我们使用Dimensions API 计算聚光灯的偏移量。/ /src/components/TabBar.js /import React from “react”;import { View, Text, StyleSheet, TouchableOpacity, Dimensions } from “react-native”;import posed from “react-native-pose”;const windowWidth = Dimensions.get(“window”).width;const tabWidth = windowWidth / 4;const SpotLight = posed.View({ route0: { x: 0 }, route1: { x: tabWidth }, route2: { x: tabWidth * 2 }, route3: { x: tabWidth * 3 }});const S = StyleSheet.create({ container: { flexDirection: “row”, height: 52, elevation: 2 }, tabButton: { flex: 1, justifyContent: “center”, alignItems: “center” }, spotLight: { width: tabWidth, height: “100%”, backgroundColor: “rgba(128,128,255,0.2)”, borderRadius: 8 }});const TabBar = props => { const { renderIcon, getLabelText, activeTintColor, inactiveTintColor, onTabPress, onTabLongPress, getAccessibilityLabel, navigation } = props; const { routes, index: activeRouteIndex } = navigation.state; return ( <View style={S.container}> <View style={StyleSheet.absoluteFillObject}> <SpotLight style={S.spotLight} pose={route${activeRouteIndex}} /> </View> {routes.map((route, routeIndex) => { const isRouteActive = routeIndex === activeRouteIndex; const tintColor = isRouteActive ? activeTintColor : inactiveTintColor; return ( <TouchableOpacity key={routeIndex} style={S.tabButton} onPress={() => { onTabPress({ route }); }} onLongPress={() => { onTabLongPress({ route }); }} accessibilityLabel={getAccessibilityLabel({ route })} > {renderIcon({ route, focused: isRouteActive, tintColor })} <Text>{getLabelText({ route })}</Text> </TouchableOpacity> ); })} </View> );};export default TabBar;运行效果如下:请注意,我们从未指定动画的持续时间和行为, Pos e负责使用合理的默认值。现在我们将为选中图标添加一些缩放:/ /src/components/TabBar.js /…const Scaler = posed.View({ active: { scale: 1.25 }, inactive: { scale: 1 }});…现在我们可以像这样将图标包装在 Scaler 组件中。/ /src/components/TabBar.js /<Scaler style={S.scaler} pose={isRouteActive ? “active” : “inactive”}> {renderIcon({ route, focused: isRouteActive, tintColor })}</Scaler>运行效果如下:我们的标签栏开始看起来很不错。 剩下要做的就是稍微改善一下,改变配色方案,调整我们的聚光灯,我们的组件就完成了。现在,我们可以在这里改进一些事情。 例如,当前的实现假设选项卡导航器中总会有 4 个 Screen,聚光灯颜色在选项卡栏组件中是写死。样式应该通过路由器上的 tabBarOptions 配置进行动态编写的,这边不会讲这些,大家自己动手做做。TabBar 组件的完整代码:/ /src/components/TabBar.js /import React from “react”;import { View, Text, StyleSheet, TouchableOpacity, Dimensions} from “react-native”;import posed from “react-native-pose”;const windowWidth = Dimensions.get(“window”).width;const tabWidth = windowWidth / 4;const SpotLight = posed.View({ route0: { x: 0 }, route1: { x: tabWidth }, route2: { x: tabWidth * 2 }, route3: { x: tabWidth * 3 }});const Scaler = posed.View({ active: { scale: 1.25 }, inactive: { scale: 1 }});const S = StyleSheet.create({ container: { flexDirection: “row”, height: 52, elevation: 2, alignItems: “center” }, tabButton: { flex: 1 }, spotLight: { width: tabWidth, height: “100%”, justifyContent: “center”, alignItems: “center” }, spotLightInner: { width: 48, height: 48, backgroundColor: “#ee0000”, borderRadius: 24 }, scaler: { flex: 1, alignItems: “center”, justifyContent: “center” }});const TabBar = props => { const { renderIcon, activeTintColor, inactiveTintColor, onTabPress, onTabLongPress, getAccessibilityLabel, navigation } = props; const { routes, index: activeRouteIndex } = navigation.state; return ( <View style={S.container}> <View style={StyleSheet.absoluteFillObject}> <SpotLight style={S.spotLight} pose={route${activeRouteIndex}}> <View style={S.spotLightInner} /> </SpotLight> </View> {routes.map((route, routeIndex) => { const isRouteActive = routeIndex === activeRouteIndex; const tintColor = isRouteActive ? activeTintColor : inactiveTintColor; return ( <TouchableOpacity key={routeIndex} style={S.tabButton} onPress={() => { onTabPress({ route }); }} onLongPress={() => { onTabLongPress({ route }); }} accessibilityLabel={getAccessibilityLabel({ route })} > <Scaler pose={isRouteActive ? “active” : “inactive”} style={S.scaler} > {renderIcon({ route, focused: isRouteActive, tintColor })} </Scaler> </TouchableOpacity> ); })} </View> );};export default TabBar;路由器配置如下:/ /src/router/router.js /…const TabNavigator = createBottomTabNavigator( / screen config ommited */, { tabBarComponent: TabBar, tabBarOptions: { activeTintColor: “#eeeeee”, inactiveTintColor: “#222222” } });你的点赞是我持续分享好东西的动力,欢迎点赞!欢迎加入前端大家庭,里面会经常分享一些技术资源。 ...

April 16, 2019 · 5 min · jiezi

React-Native从搭建环境到 发布 APP 指北

开始前的话语:1、由于andriod studio不易下载,并且占用内存大,运行的AVD模拟器非常迟钝。所以本文采用genymotion模拟器搭建,它更加轻量,运行更流畅。2、由于很多学习react的用户,都是在windows电脑上开发,完了顺便学习下react-native,所以本文是用于搭建android环境的(mac电脑没钱买,但不好意思说)开发环境要求:Node 的版本必须高于 8.3,Python 的版本必须为 2.x(不支持 3.x),而 JDK 的版本必须是 1.8(目前不支持 1.9 及更高版本)android版本为9(由于最新的react native默认为9,其实其他版本也行,但要改配置,比较麻烦)一、环境搭建1、jdk下载及其环境变量配置如果学过java,则忽略本步骤。如果小白,则继续阅读点击JDK官网,下载对应版本的jdk,然后双击安装。然后一路“下一步”。默认会安装在C盘 C:Program FilesJavajdk1.8.0_201 路径下配置环境变量桌面–>我的电脑–>右键——>属性点击"高级系统设置"点击"环境变量"编辑用户变量Path新建,将刚才安装的jdk路径复制到输入框中。最后别忘了,点击“确定”关闭对话框。然后打开cmd,输入>java -version如果出现版本号,则说明jdk配置完毕。2、python下载及其环境变量配置进入Python官网下载对应版本,然后双击安装,默认一路“下一步”类似jdk环境变量,将python的安装路径,配置到环境变量中。3、SDK下载虽然我们不需要android studio来开发react-native,但是在启动react时,如果启动的是android,则还是要sdk包的支持和编译。才能将app安装到genymotion模拟器中运行。我们只需要下载sdk manage来管理sdk包,可以不用任何翻墙和代理,即可下载。速度还很快这是我的sdk manage的百度网盘地址:链接:https://pan.baidu.com/s/1uUmz… 提取码:m3fl 下载完,双击安装,一路"下一步"。然后配置sdk的环境变量,但是需要注意,不是加入到path中,而是新建个名为ANDROID_HOME的变量,然后将刚才sdk安装的路径设置到变量值中然后,进入到sdk安装目录,找到s并双击打开。找到android 9,展开勾选这两个,然后点击右下角install packages,稍微等待会,即可看到这两个包后面的"not installed"变成了"installed"二、Genymotion模拟器下载genymotion官网下载前,必须要注册账号,并登陆。登陆成功后,点击右上角红色的"Download"由于我们是个人用户,所以往页面下方拉,会看到"Get Genymotion personal version",点击进入下载。下载上方的包含有VirtualBox的版本。下载成功并安装。启动桌面上的"Genymotion"快捷方式,打开genymotion.进入setting首先登陆配置ADB中的sdk为刚才安装sdk的目录。然后关闭选择android 9版本的模拟器,并安装模拟器安装成功后,start启动出现如下的页面,即可表明启动成功。三、react native项目创建首先安装react-native-cli>npm install -g yarn react-native-cli然后使用init,创建项目,官网实例名为AwesomeProject,咱们也用这个吧。react-native init AwesomeProject进入AwesomeProject项目cd AwesomeProjectreact-native run-android即可在模拟器上看到react-native中的内容使用vscode打开AwesomeProject项目,打开App.js,在render中稍微修改文字,并打开genymotion模拟器,双击键盘R键(自己办公桌的键盘,不是genymotion模拟器的软键盘),即可刷新模拟器上的页面。同时,在android的outputs文件夹下,可以编译好的apk,但是这个apk是没有经过数字证书认证的,无法发布到应用商店的。四、采用数字证书编译App使用管理员权限打开cmd命令行工具,然后进入到jdk的bin目录:C:Program FilesJavajdk1.8.0_201bin 目录然后再控制台输入如下命令:keytool -genkey -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000然后会提示你输入秘钥密码,地区,行政区,国家等等,完成后。在bin目录下会有个my-release-key.keystore文件将次秘钥文件复制到react native项目的androiud/app下修改gradle.properties文件,加入如下代码:MYAPP_RELEASE_STORE_FILE=my-release-key.keystoreMYAPP_RELEASE_KEY_ALIAS=my-key-aliasMYAPP_RELEASE_STORE_PASSWORD=*****MYAPP_RELEASE_KEY_PASSWORD=***注意部分要用你刚才申请秘钥时输入的密码替换进入android/app/build.gradle中,编辑文件,新增红色部分。然后进入到android目录下,输入命令。gradlew assembleRelease即可使用数字证书来打包app,成功后,会在apk下多出来一个realese文件夹(如果没有,点击右上角刷新)为了确保发布到应用商店的apk没有问题,我们还得把这个apk在genymotion模拟器上运行下,来简单测试下输入命令>react-native run-android –variant=release即可在模拟器上,看到有个app被安装上了。

March 5, 2019 · 1 min · jiezi

windows系统安装配置react-native运行环境

最近公司要开发react-native项目,自己在windows系统上练习了一下,过程中发现好多问题,在这里整理出来供大家参考;一、首先来看一下reactNative官网官网上的教程很详细,介绍了IOS和Android的环境搭建、示例教程等等,建议大家先按照官网的环境搭建教程尝试搭建,遇到问题再上网搜索答案,这样印象会深刻一些;下面就按照官网教程来详细讲解一下IOS和Android的环境搭建二、IOS和Android的环境搭建稳定的-Fan Qiang-工具安装 Android Studio 需要-Fan Qiang-才能下载,安装配置 Android Studio 的时候也要用到-Fan Qiang,所以你需要有一个稳定的-Fan Qiang-工具;(注意稳定,否则会出现下载失败、链接超时的情况)我用的是小飞机,就不在这里多说了,大家自行搜索;NodeJs下载Node版本必须高于8.3。Python2下载Python 的版本必须为 2.x(不支持 3.x)JDK下载JDK 的版本必须是 1.8(目前不支持 1.9 及更高版本)- 下载安装Android Studio 上步操作完成就开始下载 Android Studio; 官网上介绍安装是这样说的: 安装界面中选择"Custom"选项,确保选中了以下几项: Android SDK Android SDK Platform Performance (Intel ® HAXM) (AMD 处理器看这里) Android Virtual Device 然后点击"Next"来安装选中的组件。 如果选择框是灰的,你也可以先跳过,稍后再来安装这些组件。 我安装的时候,这几项确实是不能选中的,所以直接“Next” ,如果你的-Fan Qiang-工具足够稳定,那就不用担心,后面的步骤中会让你安装这些的,所以按照官网教程往下走就可以了;- 配置 ANDROID_HOME 环境变量这里直接从官网copy了React Native 需要通过环境变量来了解你的 Android SDK 装在什么路径,从而正常进行编译。打开控制面板 -> 系统和安全 -> 系统 -> 高级系统设置 -> 高级 -> 环境变量 -> 新建,创建一个名为ANDROID_HOME的环境变量(系统或用户变量均可),指向你的 Android SDK 所在的目录(具体的路径可能和下图不一致,请自行确认):SDK 默认是安装在下面的目录:c:Users你的用户名AppDataLocalAndroidSdk你可以在 Android Studio 的"Preferences"菜单中查看 SDK 的真实路径,具体是Appearance & Behavior → System Settings → Android SDK。你需要关闭现有的命令符提示窗口然后重新打开,这样新的环境变量才能生效。- 把 platform-tools 目录添加到环境变量 Path 中打开控制面板 -> 系统和安全 -> 系统 -> 高级系统设置 -> 高级 -> 环境变量,选中Path变量,然后点击编辑。点击新建然后把 platform-tools 目录路径添加进去。此目录的默认路径为:c:Users你的用户名AppDataLocalAndroidSdkplatform-tools - 安装 Android SDK在 Android Studio 的欢迎界面中找到 SDK Manager。点击"Configure",然后就能看到"SDK Manager"在 SDK Manager 中选择"SDK Platforms"选项卡,然后在右下角勾选"Show Package Details"。展开Android 9 (Pie)选项,确保勾选了下面这些组件(重申你必须使用稳定的-Fan Qiang-工具,否则可能都看不到这个界面): Android SDK Platform 28Intel x86 Atom_64 System Image(官方模拟器镜像文件,使用非官方模拟器不需要安装此组件)然后点击"SDK Tools"选项卡,同样勾中右下角的"Show Package Details"。展开"Android SDK Build-Tools"选项,确保选中了 React Native 所必须的28.0.3版本。你可以同时安装多个其他版本。最后点击"Apply"来下载和安装这些组件。- 安装安卓虚拟机不建议使用Android Studio自带的虚拟机,因为据说是性能较差、操作不方便等问题;推荐使用Genymotion,企业版是收费的,但是个人版本是免费的,大家可以选择个人版本进行下载;1、首先注册2、选择个人版本(免费),下载vbox版本3、下载、安装完成后登录:4、登录成功后会出现安卓机型列表,点击想要安装的虚拟机后面的“三个点”进行下载安装;虚拟机启动成功!三、一切准备就绪,现在开始创建reactNative项目**使用 React Native 命令行工具来创建一个名为"AwesomeProject"的新项目:1、react-native init AwesomeProject创建成功后在文件资源管理器中会看到 AwesomeProject 这个文件夹2、cd AwesomeProject3、react-native run-android运行这一步骤的时候后会打开node界面第三步很容易出现问题,这一步严重依赖-Fan Qiang-工具,建议在确保工具正常巡行的情况下执行此步骤,如果出现失败等问题,请检查工具是否运行正常;项目运行成功!参考文档:https://reactnative.cn/docs/g… ...

February 27, 2019 · 1 min · jiezi