技术标签: react.js react native javascript
当我用了2天翻越了无数博客文档才搭建起react-native的开发环境之后(忘记记录踩坑指南了@_@),因为使用的是最新版的mac pro,一部分的坑网上的解决方法已经失效了,第二就是大家都懂得网络问题,这个只能多试试各种方法进行安装一些依赖,另外我使用小米手机报错‘Execution failed for task ':app:installDebug’时,在设置----更多设置----开发者选项----启用MIUI优化 关闭之后就可以解决,那么就可以正式开始我的react-native学习之旅。
首先按照官网进行脚手架创建项目: https://reactnative.dev/docs/environment-setup
如果你很熟悉react,那么react-native的语法应当不成问题,当然react-native在很多地方与web开发还是有很大的区别,例如入口可以用index.ios.js和index.android.js来区分安卓和ios的入口文件,还有ios和安卓的兼容问题,以及调用原生接口的问题等等,先把App.js本身的代码清干净,引入我们的第一天学习的文件代码
app.js
StyleSheet, useColorScheme, View 三个react-native的组件,分别对应api来看一下如何使用的。
StyleSheet 是类似于 CSS StyleSheets 的抽象,常用的就是const styles = StyleSheet.create({ fontSize: 30 }) ,使用时在对应的组件中写style={[ fontSize: 30 ]},在RN中样式布局和web中有一定的区别需要花费一定的时间进行学习。
useColorScheme自定义hooks,React钩子提供并订阅来自Appearance模块的配色方案更新。返回值表示当前用户首选的配色方案。该值可以稍后更新,既可以通过直接的用户操作(例如在设备设置中选择主题),也可以根据时间表(例如,遵循白天和黑夜循环的明暗主题)进行更新。
"light"
: The user prefers a light color theme."dark"
: The user prefers a dark color theme.null
: The user has not indicated a preferred color theme.View是构建UI最基本的组件,它是一个容器,支持flexbox布局、样式、一些触摸处理和可访问控件。View直接映射到React native运行的平台上的原生视图,无论是UIView, <div>,android。视图,等等。类似web开发中的div,但是在react-native中布局主要是用flex布局,和web开发有一定的区别。
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* @format
* @flow strict-local
*/
import React from 'react';
import {
Node} from 'react';
import Day1 from './view/day1';
import {
useColorScheme, View } from 'react-native';
import {
Colors } from 'react-native/Libraries/NewAppScreen';
const App: () => Node = () => {
const isDarkMode = useColorScheme() === 'dark';
const backgroundStyle = {
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
};
return (
<View style={
backgroundStyle}>
<Day1 />
</View>
);
};
export default App;
Day1.js
Platform, FlatList, StyleSheet, StatusBar, Text, TouchableHighlight 几个react-native的组件,分别对应api来看一下如何使用的。
Platform用于区分ios系统和Android系统,然后针对ios和android进行兼容。常用:
React Native会检测某个文件是否具有.ios.或是.android.的扩展名,然后根据当前运行的平台加载正确对应的文件。
假设你的项目中有如下两个文件:
`BigButton.ios.js`
`BigButton.android.js`
这样命名组件后你就可以在其他组件中直接引用,而无需关心当前运行的平台是哪个。
`import BigButton from './components/BigButton';`
var {
Platform } = React;
var styles = StyleSheet.create({
container: {
flex: 1,
...Platform.select({
ios: {
backgroundColor: 'red',
},
android: {
backgroundColor: 'blue',
},
}),
},
});
//上面的代码会根据平台的不同返回不同的container样式——iOS上背景色为红色,而android为蓝色。
这一方法可以接受任何合法类型的参数,因此你也可以直接用它针对不同平台返回不同的组件,像下面这样:
var Component = Platform.select({
ios: () => require('ComponentIOS'),
android: () => require('ComponentAndroid'),
})();
<Component />
React Native提供了一个检测当前运行平台的模块。如果组件只有一小部分代码需要依据平台定制,那么这个模块就可以派上用场。
import {
Platform } from 'react-native';
var styles = StyleSheet.create({
height: (Platform.OS === 'ios') ? 200 : 100,
});
//Platform.OS在iOS上会返回ios,而在Android设备或模拟器上则会返回android。
//在Android上,平台模块还可以用来检测当前所运行的Android平台的版本:
import {
Platform } from 'react-native';
if(Platform.Version === 21){
console.log('Running on Lollipop!');
}
用于展示列表,同时兼容多个平台,并且可以支持选择点击高亮。
一个用于显示文本的 React 组件,并且它也支持嵌套、样式,以及触摸处理。
本组件用于封装视图,使其可以正确响应触摸操作。当按下的时候,封装的视图的不透明度会降低,同时会有一个底层的颜色透过而被用户看到,使得视图变暗或变亮。其实就是button
/**
* Day 1
* A stop watch
*/
'use strict';
import React, {
Component} from 'react';
import {
Platform, FlatList, StyleSheet, StatusBar, Text, TouchableHighlight, View} from 'react-native';
import Util from './utils';
import PropTypes from 'prop-types'; // 由于react的propTypes早就被移除了 所以需要从外部引
class WatchFace extends Component {
static propTypes = {
sectionTime: PropTypes.string.isRequired,
totalTime: PropTypes.string.isRequired,
};
render() {
return (
<View style={
styles.watchFaceContainer}>
<Text style={
styles.sectionTime}>{
this.props.sectionTime}</Text>
<Text style={
styles.totalTime}>{
this.props.totalTime}</Text>
</View>
);
}
}
class WatchControl extends Component {
static propTypes = {
stopWatch: PropTypes.func.isRequired,
clearRecord: PropTypes.func.isRequired,
startWatch: PropTypes.func.isRequired,
addRecord: PropTypes.func.isRequired,
};
constructor(props) {
super(props);
this.state = {
watchOn: false,
startBtnText: '启动',
startBtnColor: '#60B644',
stopBtnText: '计次',
underlayColor: '#fff',
};
}
_startWatch() {
if (!this.state.watchOn) {
this.props.startWatch();
this.setState({
startBtnText: '停止',
startBtnColor: '#ff0044',
stopBtnText: '计次',
underlayColor: '#eee',
watchOn: true,
});
} else {
this.props.stopWatch();
this.setState({
startBtnText: '启动',
startBtnColor: '#60B644',
stopBtnText: '复位',
underlayColor: '#eee',
watchOn: false,
});
}
}
_addRecord() {
if (this.state.watchOn) {
this.props.addRecord();
} else {
this.props.clearRecord();
this.setState({
stopBtnText: '计次',
});
}
}
render() {
return (
<View style={
styles.watchControlContainer}>
<View style={
{
flex: 1, alignItems: 'flex-start'}}>
<TouchableHighlight
style={
styles.btnStop}
underlayColor={
this.state.underlayColor}
onPress={
() => this._addRecord()}>
<Text style={
styles.btnStopText}>{
this.state.stopBtnText}</Text>
</TouchableHighlight>
</View>
<View style={
{
flex: 1, alignItems: 'flex-end'}}>
<TouchableHighlight style={
styles.btnStart} underlayColor="#eee" onPress={
() => this._startWatch()}>
<Text style={
[styles.btnStartText, {
color: this.state.startBtnColor}]}>{
this.state.startBtnText}</Text>
</TouchableHighlight>
</View>
</View>
);
}
}
class WatchRecord extends Component {
static propTypes = {
record: PropTypes.array.isRequired,
};
constructor(props) {
super(props);
this.Item = ({
item}) => {
return (
<View style={
styles.recordItem}>
<Text style={
styles.recordItemTitle}>{
item.title || ''}</Text>
<View style={
{
alignItems: 'center'}}>
<Text style={
styles.recordItemTime}>{
item.time || ''}</Text>
</View>
</View>
);
};
}
render() {
return (
<FlatList
keyExtractor={
(item) => `${
item.title}-${
item.time}`}
style={
styles.recordList}
data={
this.props.record}
renderItem={
this.Item}
/>
);
}
}
export default class extends Component {
constructor() {
super();
this.state = {
stopWatch: false,
resetWatch: true,
intialTime: 0,
currentTime: 0,
recordTime: 0,
timeAccumulation: 0,
totalTime: '00:00.00',
sectionTime: '00:00.00',
recordCounter: 0,
record: [],
};
}
componentWillUnmount() {
this._stopWatch();
this._clearRecord();
}
componentDidMount() {
if (Platform.OS === 'ios') {
StatusBar.setBarStyle(0);
}
}
_startWatch() {
if (this.state.resetWatch) {
this.setState({
stopWatch: false,
resetWatch: false,
timeAccumulation: 0,
initialTime: new Date().getTime(),
});
} else {
this.setState({
stopWatch: false,
initialTime: new Date().getTime(),
});
}
let milSecond, second, minute, countingTime, secmilSecond, secsecond, secminute, seccountingTime;
let interval = setInterval(() => {
this.setState({
currentTime: new Date().getTime(),
});
countingTime = this.state.timeAccumulation + this.state.currentTime - this.state.initialTime;
minute = Math.floor(countingTime / (60 * 1000));
second = Math.floor((countingTime - 6000 * minute) / 1000);
milSecond = Math.floor((countingTime % 1000) / 10);
seccountingTime = countingTime - this.state.recordTime;
secminute = Math.floor(seccountingTime / (60 * 1000));
secsecond = Math.floor((seccountingTime - 6000 * secminute) / 1000);
secmilSecond = Math.floor((seccountingTime % 1000) / 10);
this.setState({
totalTime:
(minute < 10 ? '0' + minute : minute) +
':' +
(second < 10 ? '0' + second : second) +
'.' +
(milSecond < 10 ? '0' + milSecond : milSecond),
sectionTime:
(secminute < 10 ? '0' + secminute : secminute) +
':' +
(secsecond < 10 ? '0' + secsecond : secsecond) +
'.' +
(secmilSecond < 10 ? '0' + secmilSecond : secmilSecond),
});
if (this.state.stopWatch) {
this.setState({
timeAccumulation: countingTime,
});
clearInterval(interval);
}
}, 10);
}
_stopWatch() {
this.setState({
stopWatch: true,
});
}
_addRecord() {
let {
recordCounter, record} = this.state;
recordCounter++;
if (recordCounter > 5) {
record.pop();
}
record.unshift({
title: '计次' + recordCounter, time: this.state.sectionTime});
this.setState({
recordTime: this.state.timeAccumulation + this.state.currentTime - this.state.initialTime,
recordCounter: recordCounter,
record: record,
});
//use refs to call functions within other sub component
//can force to update the states
// this.refs.record._updateData();
}
_clearRecord() {
this.setState({
stopWatch: false,
resetWatch: true,
intialTime: 0,
currentTime: 0,
recordTime: 0,
timeAccumulation: 0,
totalTime: '00:00.00',
sectionTime: '00:00.00',
recordCounter: 0,
record: [],
});
}
render() {
return (
<View style={
styles.watchContainer}>
<WatchFace totalTime={
this.state.totalTime} sectionTime={
this.state.sectionTime} />
<WatchControl
addRecord={
() => this._addRecord()}
clearRecord={
() => this._clearRecord()}
startWatch={
() => this._startWatch()}
stopWatch={
() => this._stopWatch()}
/>
<WatchRecord record={
this.state.record} />
</View>
);
}
}
const styles = StyleSheet.create({
watchContainer: {
alignItems: 'center',
backgroundColor: '#f3f3f3',
marginTop: 60,
},
watchFaceContainer: {
width: Util.size.width,
paddingTop: 50,
paddingLeft: 30,
paddingRight: 30,
paddingBottom: 40,
backgroundColor: '#fff',
borderBottomWidth: 1,
borderBottomColor: '#ddd',
height: 170,
},
sectionTime: {
fontSize: 20,
fontWeight: '100',
paddingRight: 30,
color: '#555',
position: 'absolute',
left: Util.size.width - 140,
top: 30,
},
totalTime: {
fontSize: Util.size.width === 375 ? 70 : 60,
fontWeight: '100',
color: '#222',
paddingLeft: 20,
},
watchControlContainer: {
width: Util.size.width,
height: 100,
flexDirection: 'row',
backgroundColor: '#f3f3f3',
paddingTop: 30,
paddingLeft: 60,
paddingRight: 60,
paddingBottom: 0,
},
btnStart: {
width: 70,
height: 70,
borderRadius: 35,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
btnStop: {
width: 70,
height: 70,
borderRadius: 35,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
btnStartText: {
fontSize: 14,
backgroundColor: 'transparent',
},
btnStopText: {
fontSize: 14,
backgroundColor: 'transparent',
color: '#555',
},
recordList: {
width: Util.size.width,
height: Util.size.height - 300,
paddingLeft: 15,
},
recordItem: {
height: 40,
borderBottomWidth: Util.pixel,
borderBottomColor: '#bbb',
paddingTop: 5,
paddingLeft: 10,
paddingRight: 10,
paddingBottom: 5,
flexDirection: 'row',
alignItems: 'center',
},
recordItemTitle: {
backgroundColor: 'transparent',
flex: 1,
textAlign: 'left',
paddingLeft: 20,
color: '#777',
},
recordItemTime: {
backgroundColor: 'transparent',
flex: 1,
textAlign: 'right',
paddingRight: 20,
color: '#222',
},
});
文章浏览阅读481次。下面介绍的这些免费后端管理HTML模板,都非常不错。建议您收藏。Charisma是一个响应式管理模板,基于Twitter Bootstrap构建。拥有9种外观主题,包括几乎所有的东西,如表单、图表、按纽、表格、文件管理器、相册等。可到GitHub link下载该模板。INADMIN是一个基于jQuery开发的管理模板,拥有头+顶部导航,提供了tables、forms、messages等样式,还..._java后端查询内容的数据赋值定制的html 模板
文章浏览阅读1.7k次。1.4.3 圆 - vue-amap 中文文档 - 文江博客基础示例 组件 | vue-amap
文章浏览阅读5.8k次,点赞11次,收藏33次。几何光学学习笔记(1)1.1 几何光学的基本概念和定律1.绪论2. 几何光学的基本概念3.几何光学的基本规律1.绪论几何光学:直线传播;互不影响;折射反射。物理光学:波动光学,量子光学几何光学和物理光学在一定条件下可以统一起来。例如:几何光学认为光源通过光学系统会成像为一个几何点;而物理光学则认为会成像为一个黑白相间的衍射斑。其中,第一个亮斑的半径为y=1.22λDy=\frac {1.22\lambda} Dy=D1.22λ当λ→0\lambda\to0λ→0时,y也为0,此时几何光
文章浏览阅读685次。注意 注意 请注意:一、Frida介绍Frida是一个可以hook App的动态代码工具包,可以向Windows、macOS、Linux、iOS、Android和QNX的本机应用程序中注入JavaScript或自己的库代码。最开始的时候,它是基于谷歌的V8 Javascript运行,但是从版本9开始,Frida已经开始使用其内部的Duktape运行。列举一些Frida的使用场景:1、hookin..._python hook ios app
文章浏览阅读935次。在每次操作的时候都会查询一遍权限,说实话,确实有点压力,所以可以考虑采用一下缓存来缓解一下压力Ehcache本地缓存的实现1、<!-- shiro缓存管理器 --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-ehcache</artifactId> <vers_shiro-activesessioncache
文章浏览阅读325次。今天搜索关于谷歌所使用的技术的时候看到CSDN上的文章,随便看了看自己的,发现自己有快两年没有写过了,真是汗颜啊,所以决定以后关于技术的全放到程序员宅基地上,同时保留163博客上的内容 还希望各位朋友多多捧场
文章浏览阅读1.6k次,点赞2次,收藏2次。notepad++是一款在windows上表现很不错的编辑器,学习成本低,支持的语言多,可拓展性高。 我原本打算用notepad++做为主编辑器,但是发现他对markdown的支持并不好,况且优秀的编辑器有很多。我打算去探索新的编辑器。 目前,notepad++依然有用武之地,因为通过notepadstarterplugin插件能完全取代记事本,即一些默认打开记事本的程序,将会打开notepad++,非常_notepad加粗快捷键
文章浏览阅读760次,点赞8次,收藏7次。计算 MD5 摘要需要导入HarmonyOs提供的统一的密码算法库加解密相关接口。_harmony md5
文章浏览阅读6.5w次,点赞10次,收藏55次。Windows 解决cmd/dos窗口中文乱码问题,本文提供了多种解决方案,总有一款适合你!_cmd中文乱码解决方法
文章浏览阅读87次。1.css在不同浏览器下显示效果不同firefox和IE对某些css样式的认定有不少区别,包括:· ul和ol的默认padding值是不一样的,在Firefox中,padding-left默认值为40px左右,而IE中为0,一般设置ul{margin:0;padding:0;}就能解决大部分问题· ..._火狐 p height 多了 0.45
文章浏览阅读657次。finally块用于在异常时释放资源。资源可能是文件,网络连接,数据库连接等,finally块执行代码运行保证。以下程序说明了finally块的用法。Scala finally块示例class ExceptionExample{ def divide(a:Int, b:Int) = { try{ a/b ..._scala finally
文章浏览阅读2.8k次。嵌入式系统的启动都是类似的,先启动一个boot程序,然后又boot控制系统的进一步加载运行_qnx启动时序图