React Native学习心得 Myth丶恋晨 2022-03-28 05:41 220阅读 0赞 * 目前通过《React Native移动开发实战-向洪治版》进行基础学习 * 结合网址进行学习:[https://reactnative.cn/][https_reactnative.cn] * 讨论社区:[https://www.facebook.com/groups/react.native.community][https_www.facebook.com_groups_react.native.community] * React Native - 调试技巧及调试菜单说明(模拟器调试、真机调试):[http://www.hangge.com/blog/cache/detail\_1480.html][http_www.hangge.com_blog_cache_detail_1480.html] * 样式:[https://reactnative.cn/docs/layout-props/][https_reactnative.cn_docs_layout-props] * 图标库地址:[https://oblador.github.io/react-native-vector-icons/][https_oblador.github.io_react-native-vector-icons] 一、配置环境 * mac安装环境 可以根据书12页进行参考,也可以根据网站[https://reactnative.cn/docs/getting-started.html][https_reactnative.cn_docs_getting-started.html],主要还是参考网站配置环境 1.安装完node之后检查电脑是否安装node 通过cd,返回到最根目录,然后如下操作 node -v mac电脑 ![201901091825065.png][] 2.安装npm npm install -g react-native-cli 安装完node之后设置下npm镜像 npm config set registry https://registry.npm.taobao.org --global npm config set disturl https://npm.taobao.org/dist --global 3.安装yarn brew install yarn 4.mac电脑安装xcode 按照网站指示下载安装xcode 启动xcode之后,按照下图点击 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70][] mac安装完成 * windows安装环境 可以根据书12页进行参考,也可以根据网站[https://reactnative.cn/docs/getting-started.html][https_reactnative.cn_docs_getting-started.html],主要还是参考网站配置环境 windows下可以参考[https://blog.csdn.net/zeping891103/article/details/85769957][https_blog.csdn.net_zeping891103_article_details_85769957] 1.安装完node之后检查电脑是否安装node 通过cd,返回到最根目录,然后如下操作 node -v windows电脑 ![20190109212925911.png][] 2.安装npm npm install -g yarn npm install -g yarn react-native-cli 安装完node之后设置下npm镜像 npm config set registry https://registry.npm.taobao.org --global npm config set disturl https://npm.taobao.org/dist --global 3.安装Python2 下载网址:[https://www.python.org/downloads/][https_www.python.org_downloads] 选择合适的版本点击下载 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 1][] 点击下载后跳到如下新页面,再次点击适合自己的电脑版本,即可下载成功,按照指示安装即可 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 2][] 4.检查安装的java版本( JDK 的版本必须是 1.8(目前不支持 1.9 及更高版本) java -version ![20190110215738327.png][] * mac创建新项目 1.创建时遇见如下问题: ![20190110112056869.png][] 报上面那个错误,说明在安装过程中,某个命令行工具没有安装成功,依次检查一下 最后发现是react-native-cli没有安装成功 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 3][] 2.创建新项目 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 4][] 一直没有创建成功,说明环境没有配置好,由于mac电脑在安装完xcode之后,ios环境也随之安装好了。目前需要安装andriod环境 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 5][] 配置 ANDROID\_HOME 环境变量时,在终端下使用`vi ~/.bash_profile`命令创建或编辑 创建成功后将 export ANDROID_HOME=$HOME/Library/Android/sdk export PATH=$PATH:$ANDROID_HOME/tools export PATH=$PATH:$ANDROID_HOME/tools/bin export PATH=$PATH:$ANDROID_HOME/platform-tools export PATH=$PATH:$ANDROID_HOME/emulator 复制进去,然后输入:wq,将`.bash_profile`文件进行的编辑操作进行保存后退出。如果路径不同,则将刚刚复制的第一行代码修改一下路径即可 在官网中将目标平台修改为andriod,按照提示进行操作 * 在ios上运行 react-native init AwesomeProject cd AwesomeProject react-native run-ios 运行后,出现报错: ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 6][] 解决办法:[https://www.crifan.com/react\_native\_ios\_run\_again\_error\_no\_bundle\_url\_present/][https_www.crifan.com_react_native_ios_run_again_error_no_bundle_url_present] 暂时取消全局网络代理,改为自动模式即可。或者将自动模式关闭一下,退出当前模拟器,退出终端,运行成功后,再打开自动模式即可解决 成功运行后,界面上跳出一个手机的模型,页面显示内容 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 7][] 页面停留一会后,自动跳转到页面 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 8][] 终于把ios开发配置好了,开森一下下 * 在andriod上运行 1.创建一个虚拟设备 首先打开安装的 Android Studio,用它打开我们上面创建的AwesomeProject下面的-"android"目录(下面会出现报错,需要"Android SDK Build-Tools"选项,mac电脑确保选中了 React Native 所必须的28.0.3版本) (下面会出现报错,需要"Android SDK Build-Tools"选项,windows确保选中了 React Native 所必须的27.0.3版本) ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 9][] 点击上面的按钮后,弹出新的窗口 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 10][] 创建需要的手机型号,然后 cd AwesomeProject react-native run-android 出现如下问题,下面提示是java version安装版本的问题 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 11][] React Native 需要 Java Development Kit \[JDK\] 1.8(暂不支持 1.9 及更高版本) ls /Library/Java/JavaVirtualMachines/ 即可查看你电脑中装了哪些jdk版本。卸载不合适的jdk版本 sudo rm -rf /Library/Java/JavaVirtualMachines/你需要卸载的版本号.jdk ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 12][] 运行后首先跳出界面 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 13][] 几秒之后自动跳转 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 14][] 到此,andriod的环境配置成功。小小开心一下下。 * windows上配置andriod环境遇到的问题 问题1: ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 15][] 解决方案,看链接[https://stackoverflow.com/questions/47739777/android-studio-avd-emulator-process-finished-with-exit-code-1/47739865][https_stackoverflow.com_questions_47739777_android-studio-avd-emulator-process-finished-with-exit-code-1_47739865] 打开sdk management ,然后Unistal and install the Android Emulator 问题2: 运行之后,不报错,但是页面没有跳转出来: 更新了一下Android Studio这个软件就解决了 二、应用 * 小demo 执行react-native init nativeProject创建react-native项目 然后将整个项目拖入到vscode(根据个人喜好决定,本人比较习惯vscode)找到App.js,并进行简单的修改 import React, { Component } from 'react'; import { Text, View, Image } from 'react-native'; const styles = { text:{ color:'blue', fontWeight:'bold', fontSize:30 }, view:{ alignItems:'center', border:'1px solid red', marginTop:50 } } class Greeting extends Component { constructor(props){ super(props); this.state={isShowingText:true}; setInterval(() => { this.setState(()=>{ return {isShowingText:!this.state.isShowingText} }) }, 1000); } render() { if(!this.state.isShowingText){ return null; } return ( <View style={ {alignItems: 'center'}}> <Text style={styles.text}>Hello {this.props.name}!</Text> </View> ); } } class App extends Component { render() { let pic = { uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg' }; return ( <View style={styles.view}> <Image source={pic} style={ {width: 193, height: 110}} /> <Greeting name='Rexxar' /> <Greeting name='Jaina' /> <Greeting name='Valeera' /> </View> ); } } export default App 修改之后,在vscode中保存,然后react-native run-ios或者react-native run-android,在ios或者andriod中运行项目。 react-native run-ios react-native run-android 进行其他修改操作后,点击手机模拟器,分别进行页面刷新,不同手机刷新方法如下: ios: 'Press Cmd+R to reload,\\n' + 'Cmd+D or shake for dev menu', android: 'Double tap R on your keyboard to reload,\\n' + 'Shake or press menu button for dev menu', ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 16][]如左图所示,小demo已经完成。 * demo2:使用Flexbox布局,处理文本输入,处理触摸事件 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 17][] import React, { Component } from 'react'; import { Platform, Button, Text, View, TextInput, TouchableHighlight, TouchableOpacity, TouchableNativeFeedback, TouchableWithoutFeedback } from 'react-native'; const styles = { container: { flex: 2, justifyContent: 'center', padding: 60, alignItems: 'center' }, button: { marginBottom: 30, width: 260, alignItems: 'center', backgroundColor: '#2196F3' }, buttonText: { padding: 20, color: 'white' } } class App extends Component { constructor(props) { super(props); this.state = { text: '' } } _onPressButton() { alert('You tapped the button!') } _onLongPressButton() { alert('You long-pressed the button!') } render() { return ( <View style={ { flex: 1, flexDirection: 'column' }}> <View style={ { flex: 1, backgroundColor: 'powderblue', marginTop: 50 }} > <TextInput style={ { height: 40 }} placeholder="TextInput" onChangeText={(text) => this.setState({ text })} /> <Text style={ { padding: 10, fontSize: 42 }}> {this.state.text.split(' ').map((word) => word && '?').join(' ')} </Text> </View> <View style={styles.container} > <Button onPress={this._onPressButton} title="click me" color="#841584" /> <TouchableHighlight onPress={this._onPressButton} underlayColor="white"> <View style={styles.button}> <Text style={styles.buttonText}>TouchableHighlight</Text> </View> </TouchableHighlight> <TouchableOpacity onPress={this._onPressButton}> <View style={styles.button}> <Text style={styles.buttonText}>TouchableOpacity</Text> </View> </TouchableOpacity> {Platform.OS === "android" ? <TouchableNativeFeedback onPress={this._onPressButton} background={Platform.OS === 'android' ? TouchableNativeFeedback.SelectableBackground() : ''}> <View style={styles.button}> <Text style={styles.buttonText}>TouchableNativeFeedback</Text> </View> </TouchableNativeFeedback> : <View><Text>当前是iOS系统</Text></View> } <TouchableWithoutFeedback onPress={this._onPressButton} > <View style={styles.button}> <Text style={styles.buttonText}>TouchableWithoutFeedback</Text> </View> </TouchableWithoutFeedback> <TouchableHighlight onPress={this._onPressButton} onLongPress={this._onLongPressButton} underlayColor="white"> <View style={styles.button}> <Text style={styles.buttonText}>Touchable with Long Press</Text> </View> </TouchableHighlight> </View> <View style={ { flex: 1, backgroundColor: 'steelblue' }} ></View> </View> ); } } export default App * demo3:使用滚动视图 利用<ScrollView>标签实现滚动视图 import React, { Component } from 'react'; import { ScrollView, Image, Text } from 'react-native'; class App extends Component { render() { return ( <ScrollView> <Text style={ { fontSize: 196 }}>Scroll me plz</Text> <Image source={ { uri: "https://facebook.github.io/react-native/img/favicon.png", width: 64, height: 64 }} /> </ScrollView> ); } } export default App * demo4:使用长列表 FlatList更适于长列表数据,且元素个数可以增删。必须的两个属性是data和renderItem。data是列表的数据源,而renderItem则从数据源中逐个解析数据,然后返回一个设定好格式的组件来渲染。 import React, { Component } from 'react'; import { FlatList, View, Text } from 'react-native'; const styles = { container: { flex: 1, paddintTop: 22 }, item: { padding: 10, fontSize: 18, height: 44, }, } class App extends Component { render() { return ( <View style={styles.container}> <FlatList data={[ { key: 'name1' }, { key: 'name2' }, { key: 'name3' }, { key: 'name4' }, { key: 'name5' }, { key: 'name6' }, { key: 'name7' }, ]} renderItem={({ item }) => <Text style={styles.item}>{item.key}</Text>} /> </View> ); } } export default App 如果要渲染的是一组需要分组的数据,也许还带有分组标签的,那么SectionList将是个不错的选择 import React, { Component } from 'react'; import { SectionList, View, Text } from 'react-native'; const styles = { container: { flex: 1, paddintTop: 22 }, sectionHeader: { paddingTop: 120, paddingLeft: 10, paddingRight: 10, paddingBottom: 2, fontSize: 14, fontWeight: 'bold', backgroundColor: 'rgba(247,247,247,1.0)' }, item: { padding: 10, fontSize: 18, height: 44, }, } class App extends Component { render() { return ( <View style={styles.container}> <SectionList sections={[ { title: 'A', data: ['name1'] }, { title: 'B', data: ['name2', 'name3', 'name4', 'name5', 'name6', 'name7'] }, ]} renderItem={({ item }) => <Text style={styles.item}>{item}</Text>} renderSectionHeader={({ section }) => <Text style={styles.sectionHeader}>{section.title}</Text>} keyExtractor={(item, index) => index} /> </View> ); } } export default App * demo5示例教程:电影列表 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 18][] import React, { Component } from 'react'; import { Image, View, Text, FlatList } from 'react-native'; const styles = { container: { flex: 1, flexDirection:'row', justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5FCFF' }, thumbnail: { width: 53, height: 81 }, rightContainer: { flex:1, }, title:{ fontSize:20, marginBottom:8, textAlign:'center' }, year:{ textAlign:'center' }, list:{ paddingTop:20, backgroundColor:'#F5FCFF' } } const MOVIES_DATA = [ { title: '标题1', year: '2015', posters: { thumbnail: 'http://i.imgur.com/UePbdph.jpg' } }, { title: '标题2', year: '2015', posters: { thumbnail: 'http://i.imgur.com/UePbdph.jpg' } }, { title: '标题3', year: '2015', posters: { thumbnail: 'http://i.imgur.com/UePbdph.jpg' } }, { title: '标题4', year: '2015', posters: { thumbnail: 'http://i.imgur.com/UePbdph.jpg' } } ] class App extends Component { render() { return ( <FlatList data={MOVIES_DATA} renderItem={this.renderMovie} style={styles.list} // keyExtractor={item=>item.id} keyExtractor={(item, index) => index.toString()} /> ); } renderMovie({item}){ return( <View style={styles.container}> <Image source={ { uri: item.posters.thumbnail }} style={styles.thumbnail} /> <View style={styles.rightContainer}> <Text style={styles.title}>{item.title}</Text> <Text style={styles.year}>{item.year}</Text> </View> </View> ) } } export default App * React Native调试: 首先通过链接[http://www.hangge.com/blog/cache/detail\_1480.html][http_www.hangge.com_blog_cache_detail_1480.html]学习到各个调试技巧,本人最喜欢的调试方法是(mac电脑): 1.先在手机模拟器端command + D,弹出调试菜单 2.调试菜单中,选择Debug JS Remotely 3.选择后,React Native 会启动 Chrome 浏览器,并且打开一个 http://localhost:8081/debugger-ui 的新标签。 4.command+option+i,打开Chrome的开发者工具进行调试 * demo6判断当前是ios还是andriod ios ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 19][] andriod ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 20][] import React, { Component } from 'react'; import { Platform, View, Text } from 'react-native'; const styles={ container:{ flex:1, justifyContent:'center', alignItems:'center', ...Platform.select({ ios:{ backgroundColor:'yellow' }, android: { backgroundColor: "blue" } }) }, textstyle:{ color:'red', fontSize:26, fontWeight:'bold' }, } class App extends Component { render() { const iosVersion = parseInt(Platform.Version,10); console.log('iosVersion',typeof iosVersion) console.log('iosVersion',iosVersion) return ( <View style={styles.container}> <Text style={styles.textstyle}>{Platform.OS==='ios'?'ios':'android'}</Text> <Text style={styles.textstyle}>{Platform.Version>=25?'android':'null'}</Text> <Text style={styles.textstyle}>{iosVersion<25?'ios':'null'}</Text> </View> ); } } export default App 综上所述:通过Platform.OS来判断当前平台是最简单的 * demo7图片 <Image source={require("../img/preview.jpg")}></Image> <Image source={ {uri:'https://facebook.github.io/react/logo-og.png'}} style={ {width:100,height:100}}></Image> * demo8 import React, { Component } from 'react'; import { View, Text, Animated, Image } from 'react-native'; class Home extends Component { static navigationOptions = { // 设置 title title: "首页" }; state = { fadeAnim: new Animated.Value(0), // 透明度初始值设为0 } componentDidMount() { Animated.timing( // 随时间变化而执行动画 this.state.fadeAnim, // 动画中的变量值 { toValue: 1, // 透明度最终变为1,即完全不透明 duration: 10000, // 让动画持续一段时间 } ).start(); // 开始执行动画 } render() { let { fadeAnim } = this.state; return ( <Animated.View // 使用专门的可动画化的View组件 style={ { ...this.props.style, opacity: fadeAnim, // 将透明度指定为动画变量值 }} > {this.props.children} </Animated.View> ); } } // 然后你就可以在组件中像使用`View`那样去使用`FadeInView`了 class App extends React.Component { render() { return ( <View style={ {flex: 1, alignItems: 'center', justifyContent: 'center'}}> <FadeInView style={ {width: 250, height: 50, backgroundColor: 'powderblue'}}> <Text style={ {fontSize: 28, textAlign: 'center', margin: 10}}>Fading in</Text> </FadeInView> </View> ) } } export default Home * demo9动画 App.js import React, { Component } from 'react'; import { View, Text, Animated } from 'react-native'; class FadeInView extends Component { state={ fadeAnim:new Animated.Value(0),//透明度初始值设为0 } componentDidMount(){ Animated.timing( this.state.fadeAnim, { toValue:1, duration:10000, } ).start(); } render() { return ( <Animated.View style={ {...this.props.style,opacity:this.state.fadeAnim,}}>{this.props.children}</Animated.View> ); } } class Home extends Component { render() { return ( <View style={ {flex:1,alignItems:'center',justifyContent:'center'}}> <FadeInView style={ {width:250,height:50,backgroundColor:'blue'}}> <Text style={ {fontSize:28,textAlign:'center',margin:10}}>Fadding in</Text> </FadeInView> </View> ); } } export default Home * demo10 Picker, Switch, TextInput, Modal使用 import React, { Component } from 'react'; import { View, Text, Picker, Switch, TextInput, Modal, TouchableHighlight } from 'react-native'; class Home extends Component { constructor(props) { super(props); this.state = { language: this.props.defaultVal, swicthValue1: true, swicthValue2: false, text: 'TextInput组件', modalVisible: false } } _switch1 = () => { return ( <Switch style={ { marginTop: 20 }} trackColor={'#aaaa11'} value={this.state.swicthValue1} onValueChange={(value) => { //当开关状态改变了,一定要修改value的值,不然最终无法改变状态 console.log('onValueChange1 =' + value); this.setState({ swicthValue1: value }) }} testID={'one'} thumbColor={'#ff1111'} /> ) }; _switch2 = () => { return ( <Switch style={ { marginTop: 20 }} trackColor={'#aaaaff'} value={this.state.swicthValue2} onValueChange={(value) => { //当开关状态改变了,一定要修改value的值,不然最终无法改变状态 console.log('onValueChange2 =' + value); this.setState({ swicthValue2: value }) }} testID={'two'} thumbColor={'#11ff11'} /> ) }; _switch3 = () => { return ( <Switch trackColor={'#aafaff'} value={this.state.swicthValue2} onValueChange={(value) => { //当开关状态改变了,一定要修改value的值,不然最终无法改变状态 console.log('onValueChange2 =' + value); this.setState({ swicthValue2: value }) }} testID={'two'} thumbColor={'#f1ff11'} disabled={true} /> ) }; setModalVisible(visible) { this.setState({ modalVisible: visible }); } render() { return ( <View style={ { flex: 1, alignItems: 'center', justifyContent: 'center' }}> <Picker selectedValue={this.state.language} style={ { height: 50, width: 100 }} onValueChange={(itemValue) => this.setState({ language: itemValue })}> <Picker.Item label="Java" value="java" /> <Picker.Item label="JavaScript" value="js" /> </Picker> <View style={ { marginTop: 140, width: 340, height: 200, backgroundColor: '#ffffff', borderRadius: 5, alignItems: 'center' }}> {this._switch1()} {this._switch2()} <Text style={ { marginTop: 20, textAlign: 'center' }}>下面的switch设置disabled为true,无法点击,但是可以设置value的值来改变状态</Text> {this._switch3()} </View> <TextInput style={ { height: 40, borderColor: 'gray', borderWidth: 1 }} onChangeText={(text) => this.setState({ text })} value={this.state.text} /> <View style={ { marginTop: 20 }}> <Modal animationType="slide" transparent={false} visible={this.state.modalVisible} onRequestClose={() => { alert("Modal has been closed."); }}> <View style={ { marginTop: 120,alignItems:'center' }}> <View> <Text>学习modal使用!</Text> <TouchableHighlight onPress={() => { this.setModalVisible(!this.state.modalVisible);}}> <Text>Hide Modal</Text> </TouchableHighlight> </View> </View> </Modal> <TouchableHighlight onPress={() => { this.setModalVisible(true);}}> <Text>Show Modal</Text> </TouchableHighlight> </View> </View> ); } } export default Home * HTML元素与React Native组件对比 <table style="width:500px;"> <tbody> <tr> <td>HTML</td> <td>React Native</td> </tr> <tr> <td>div</td> <td>View</td> </tr> <tr> <td>img</td> <td>Image</td> </tr> <tr> <td>span,p</td> <td>Text</td> </tr> <tr> <td>li,ol</td> <td>ListView</td> </tr> </tbody> </table> 输入框组件:TextInput 滚动窗口组件:ScrollView * demo11模仿微信 文件结构图、页面效果图 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 21][] ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 22][] App.js import React, { Component } from 'react'; import Route from './src/config/route' class App extends Component { render() { return ( <Route /> ); } } export default App route.js import { createBottomTabNavigator, createStackNavigator, createAppContainer } from "react-navigation"; import React from 'react'; // 引入页面组件 import Home from '../screens/home/Home' import Details from '../screens/Details' import Tabnavigation1 from '../screens/tab1/Tabnavigation1' import Tabnavigation2 from '../screens/tab2/Tabnavigation2' import Tabnavigation3 from '../screens/tab3/Tabnavigation3' import Ionicons from 'react-native-vector-icons/Ionicons'; // 配置路由 const HomeStack = createStackNavigator({ Home: Home, Details: Details }, { initialRouteName: 'Home', defaultNavigationOptions: { headerStyle: { backgroundColor: '#010101', }, headerTintColor: '#fff', headerTitleStyle: { fontWeight: 'bold', }, } } ); const Tab1Stack = createStackNavigator({ Tabnavigation1: Tabnavigation1 }, { defaultNavigationOptions: { headerStyle: { backgroundColor: '#010101', }, headerTintColor: '#fff', headerTitleStyle: { fontWeight: 'bold', }, } } ); const Tab2Stack = createStackNavigator({ Tabnavigation2: Tabnavigation2 }, { defaultNavigationOptions: { headerStyle: { backgroundColor: '#010101', }, headerTintColor: '#fff', headerTitleStyle: { fontWeight: 'bold', }, } } ); const Tab3Stack = createStackNavigator({ Tabnavigation3: Tabnavigation3 }, { defaultNavigationOptions: { headerStyle: { backgroundColor: '#010101', }, headerTintColor: '#fff', headerTitleStyle: { fontWeight: 'bold', }, } } ); const AppNavigator = createBottomTabNavigator( { HomeStack: { screen: HomeStack, navigationOptions: { tabBarLabel: "Alisa", tabBarIcon: ({ tintColor, focused }) => ( <Ionicons name={focused ? 'ios-chatbubbles' : 'ios-home'} size={26} style={ { color: tintColor }} /> ), }, }, Tab1Stack: { screen: Tab1Stack, navigationOptions: { tabBarLabel: '通讯录', tabBarIcon: ({ tintColor }) => ( <Ionicons name='ios-people' size={26} style={ { color: tintColor }} /> ), }, }, Tab2Stack: { screen: Tab2Stack, navigationOptions: { tabBarLabel: '发现', tabBarIcon: ({ tintColor }) => ( <Ionicons name='ios-navigate' size={26} style={ { color: tintColor }} /> ), }, }, Tab3Stack: { screen: Tab3Stack, navigationOptions: { tabBarLabel: '我', tabBarIcon: ({ tintColor }) => ( <Ionicons name='ios-person' size={26} style={ { color: tintColor }} /> ), }, }, }, { tabBarOptions: { labelStyle: { fontSize: 12, }, headerTitle: { fontSize: '20', color: 'white', fontWeight: '500' }, activeTintColor: '#4dbe2d', inactiveTintColor: 'gray', } } ); const Route = createAppContainer(AppNavigator); export default Route; Home.js import React, { Component } from 'react'; import { View, Text, Image, FlatList, TouchableHighlight } from 'react-native'; import Ionicons from 'react-native-vector-icons/Ionicons'; import HomeStyle from './HomeStyle' const CHAT_DATA = [ { title: '好友1', content: '模仿微信主界面', time: 'today', posters: { thumbnail: 'http://i.imgur.com/UePbdph.jpg' } }, { title: '好友2', content: '模仿微信主界面', time: 'today', posters: { thumbnail: 'http://i.imgur.com/UePbdph.jpg' } }, { title: '好友3', content: '模仿微信主界面', time: 'today', posters: { thumbnail: 'http://i.imgur.com/UePbdph.jpg' } }, { title: '好友4', content: '模仿微信主界面', time: '2月25日', posters: { thumbnail: 'http://i.imgur.com/UePbdph.jpg' } } ] class Chat extends Component { render() { return ( <FlatList data={CHAT_DATA} renderItem={this.renderChat} // keyExtractor={item=>item.id} keyExtractor={(item, index) => index.toString()} /> ); } renderChat({ item }) { return ( <View style={HomeStyle.chatbox}> <Image source={ { uri: item.posters.thumbnail }} style={HomeStyle.thumbnail} /> <View style={HomeStyle.contentbox}> <Text style={HomeStyle.title}>{item.title}</Text> <Text style={HomeStyle.content}>{item.content}</Text> </View> <View style={HomeStyle.timebox}> <Text style={HomeStyle.time}>{item.time}</Text> </View> </View> ) } } class RightTitle extends Component { render() { return ( <View style={ { flexDirection: 'row', justifyContent: 'flex-start', alignItems: 'flex-start' }}> <Ionicons name='md-search' size={26} style={HomeStyle.rightIcon1} /> <Ionicons name='ios-add' size={26} style={HomeStyle.rightIcon2} /> </View> ); } } class Home extends Component { static navigationOptions = { // headerTitle:"Alisa", headerLeft: <Text style={HomeStyle.leftTitle}>Alisa</Text>, headerRight: <RightTitle /> }; render() { return ( <View style={HomeStyle.container}> <TouchableHighlight onPress={() => this.props.navigation.push("Details")} underlayColor="white"> <Chat /> </TouchableHighlight> </View> ); } } export default Home HomeStyle.js import React from 'react'; import { StyleSheet } from 'react-native'; export default StyleSheet.create( { leftTitle: { fontSize: 20, color: '#fff', marginLeft: 20 }, rightIcon1: { color: "#fff", marginRight: 20 }, rightIcon2: { color: "#fff", marginRight: 20 }, chatbox: { flex: 1, flexDirection: 'row', backgroundColor: '#fff', borderBottomColor:"#eee", borderBottomWidth:1, height:70, alignItems: 'center' }, thumbnail: { width: 60, height: 60, marginLeft:10, }, contentbox:{ width:'60%', marginLeft:10, flexDirection:'column' }, title: { fontSize: 16, marginBottom: 8, textAlign: 'center', textAlign:'left' }, content:{ color:'#d3d3d3', textAlign:'left' }, timebox:{ flexDirection:'row', }, time: { color:'#d3d3d3' } } ); Details.js import React, { Component } from 'react'; import { View, Text, Button } from 'react-native'; const styles = { container: { flex: 1, justifyContent: 'center', alignItems: 'center' } } class Details extends Component { static navigationOptions = { headerTitle:"聊天信息" }; render() { return ( <View style={styles.container}> <Text>Details Screen</Text> <Button title="Go to Home" onPress={() => this.props.navigation.navigate('Home')} /> <Button title="Go back" onPress={() => this.props.navigation.goBack()} /> </View> ); } } export default Details Tabnavigation1.js import React, { Component } from 'react'; import { View, ART } from 'react-native'; import Tab1Style from './Tab1Style' const { Surface, Shape, Path, Group, Text } = ART; class Tabnavigation1 extends Component { static navigationOptions = { headerTitle: "通讯录" }; render() { const linePath = Path().moveTo(1, 1).lineTo(300, 1); const juxingPath = new Path().moveTo(1, 1).lineTo(1, 99).lineTo(99, 99).lineTo(99, 1).close(); const textPath = new Path().moveTo(40, 40).lineTo(99, 10) return ( <View style={Tab1Style.container}> {/* <Text>绘制直线、虚线、矩形、文本,此处如果有Text,会与下方Text报错重复定义</Text> */} <Surface width={300} height={2} style={ { marginTop: 20 }}> <Shape d={linePath} stroke='#000000' strokeWidth={2} /> </Surface> <Surface width={300} height={2} style={ { marginTop: 20 }}> <Shape d={linePath} stroke='#000000' strokeWidth={2} strokeDash={[10, 5]} /> </Surface> <Surface width={100} height={100} style={ { marginTop: 20 }}> <Shape d={juxingPath} stroke='#000000' strokeWidth={1} fill='#892265' /> </Surface> <Surface width={100} height={100} style={ { marginTop: 20 }}> <Text stroke='#000000' strokeWidth={1} font='bold 35px Heiti SC' path={textPath} >Text</Text> </Surface> <Surface width={100} height={100}> <Group> <Shape d={juxingPath} stroke="#FFFFFF" fill="#eee" strokeWidth={1} /> <Text strokeWidth={1} strokeDash={[2, 1, 2, 1]} stroke="#000" font="bold 30px Heiti SC" path={textPath} >Group</Text> </Group> </Surface> </View> ); } } export default Tabnavigation1 Tab1Style.js import React from 'react'; import { StyleSheet } from 'react-native'; export default StyleSheet.create( { container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5FCFF', } } ); Tabnavigation2.js import React, { Component } from 'react'; import { StyleSheet, View, Text, TouchableHighlight, Image, Dimensions } from 'react-native'; import ImagePicker from 'react-native-image-picker'; import Tab2Style from './Tab2Style' const BadgeData = { data: [ { icon: "http://i.imgur.com/UePbdph.jpg", title: "Alisa分享" }, { icon: "http://i.imgur.com/UePbdph.jpg", "title": "开心网分享" }, { icon: "http://i.imgur.com/UePbdph.jpg", title: "QQ分享" }, { icon: "http://i.imgur.com/UePbdph.jpg", title: "QQ空间分享" }, { icon: "http://i.imgur.com/UePbdph.jpg", title: "QQ微博分享" }, { icon: "http://i.imgur.com/UePbdph.jpg", title: "人人网分享" }, { icon: "http://i.imgur.com/UePbdph.jpg", title: "微信分享" }, { icon: "http://i.imgur.com/UePbdph.jpg", title: "微博分享" }, { icon: "http://i.imgur.com/UePbdph.jpg", title: "朋友圈分享" } ] } //屏幕的宽度 const width = Dimensions.get('window').width; //定义一些全局的变量 const cols = 3; const boxW = 100; const vMargin = (width - cols * boxW) / (cols + 1); const hMargin = 25; //设置样式 const styles = StyleSheet.create({ container: { // 确定主轴的方向 flexDirection: 'row', // 一行显示不完的话换行显示 flexWrap: 'wrap' }, outViewStyle: { // 设置侧轴的对齐方式 alignItems: 'center', width: boxW, height: boxW, marginLeft: vMargin, marginTop: hMargin }, iconStyle: { width: 80, height: 80, marginBottom: 5 }, mainTitleStyle: { } }); const photoOptions = { title: '请选择', quality: 0.8, cancelButtonTitle: '取消', takePhotoButtonTitle: '拍照', chooseFromLibraryButtonTitle: '选择相册', allowsEditing: true, noData: false, storageOptions: { skipBackup: true, path: 'images' } }; class ImagePickerView extends Component { constructor(props) { super(props); this.state = { avatarSource: null }; this.choosePicker = this.choosePicker.bind(this) } choosePicker() { ImagePicker.showImagePicker(photoOptions, (response) => { if (response.didCancel) { console.log('User cancelled image picker'); } else if (response.error) { console.log('ImagePicker Error: ', response.error); } else if (response.customButton) { console.log('User tapped custom button: ', response.customButton); } else { let source = { uri: response.uri }; // You can also display the image using data: // let source = { uri: 'data:image/jpeg;base64,' + response.data }; this.setState({ avatarSource: source }); } }); } render() { return ( <View style={Tab2Style.imgbox}> <TouchableHighlight style={Tab2Style.button} onPress={this.choosePicker}> <Text>相机 & 相册</Text> </TouchableHighlight> <Image source={this.state.avatarSource} style={Tab2Style.imageStyle}></Image> </View> ) } } class Tabnavigation2 extends Component { static navigationOptions = { headerTitle: "发现" }; render() { return ( <View style={Tab2Style.container}> <Text>Tabnavigation2</Text> <ImagePickerView /> <View style={styles.container}> {/*返回6个包*/} {this.renderAllBadge()} </View> </View> ); } // 返回所有的包 renderAllBadge() { // 定义数组装所有的子组件 let allBadge = []; // 遍历json数据 for (let i = 0; i < BadgeData.data.length; i++) { // 取出每一个数据对象 let badge = BadgeData.data[i]; // 装入数据 allBadge.push( <View key={i} style={styles.outViewStyle}> {/* <Image style={styles.iconStyle} source={ { uri: badge.icon }} ></Image> */} <Image style={styles.iconStyle} source={ { uri: badge.icon }} ></Image> <Text style={styles.mainTitleStyle}> {badge.title} </Text> </View> ); } // 返回数组 return allBadge; } } export default Tabnavigation2 Tab2Style.js import React from 'react'; import { StyleSheet } from 'react-native'; export default StyleSheet.create( { container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor:'#fff' }, imgbox: { flex: 1, marginTop: 20, alignItems: 'center' }, button: { marginTop: 20, backgroundColor: '#808080', height: 35, width: 140, borderRadius: 5, justifyContent: 'center', alignItems: 'center' }, imageStyle: { height: 180, width: 250, marginTop: 30, alignSelf: 'center' } } ); Tabnavigation3.js import React, { Component } from 'react'; import { View, Text, FlatList, } from 'react-native'; import Tab3Style from './Tab3Style' import Ionicons from 'react-native-vector-icons/Ionicons'; const INBOX_DATA = [ { title: 'Severe Warning', content: '0 of 1 Task Completed', time: '6:07 PM' }, { title: 'Severe Warning', content: '1 of 1 Task Completed', time: 'Yesterday' }, { title: 'Moderate Warning', content: '', time: 'Yesterday' }, { title: 'Hello', content: '', time: 'Jan 21' } ] class Inbox extends Component { render() { return ( <FlatList data={INBOX_DATA} renderItem={this.renderInbox} // keyExtractor={item=>item.id} keyExtractor={(item, index) => index.toString()} /> ); } renderInbox({ item }) { return ( <View style={Tab3Style.inboxContainer}> <View style={Tab3Style.inbox_box_left}> <Text style={Tab3Style.inbox_content1_left}>{item.title}</Text> <Text style={Tab3Style.inbox_content2_left}>{item.content}</Text> </View> <View style={Tab3Style.inbox_box_right}> <Text style={Tab3Style.inbox_content1_right}>{item.time}</Text> </View> </View> ) } } class Tabnavigation3 extends Component { static navigationOptions = { headerTitle: "我" }; render() { return ( <View style={Tab3Style.totalbox}> <View style={Tab3Style.box1}> <View style={Tab3Style.box1_content1}> <Text style={Tab3Style.title}>Inbox</Text> </View> <View style={Tab3Style.box1_content2}> <Ionicons name='md-search' size={38} style={Tab3Style.rightIcon1} /> <Ionicons name='ios-add-circle' size={40} style={Tab3Style.rightIcon2} /> </View> </View> <View style={Tab3Style.box2}> <Inbox /> </View> </View> ); } } export default Tabnavigation3 Tab3Style.js import React from 'react'; import { StyleSheet } from 'react-native'; export default StyleSheet.create( { totalbox:{ display:"flex" }, box1:{ height:'40%', borderBottomColor:"#eee", borderBottomWidth:1, flexDirection:'row', alignItems: 'center', padding:20, width:'100%' }, box1_content1:{ width:'30%' }, title:{ fontSize:40, fontWeight:'bold' }, box1_content2:{ flexDirection:'row', width:'70%', justifyContent:'flex-end' }, rightIcon1: { color: "#747474", marginRight: 20 }, rightIcon2: { color: "#a526fb", marginRight: 20 }, } ); * demo12 [https_reactnative.cn]: https://reactnative.cn/ [https_www.facebook.com_groups_react.native.community]: https://www.facebook.com/groups/react.native.community [http_www.hangge.com_blog_cache_detail_1480.html]: http://www.hangge.com/blog/cache/detail_1480.html [https_reactnative.cn_docs_layout-props]: https://reactnative.cn/docs/layout-props/ [https_oblador.github.io_react-native-vector-icons]: https://oblador.github.io/react-native-vector-icons/ [https_reactnative.cn_docs_getting-started.html]: https://reactnative.cn/docs/getting-started.html [201901091825065.png]: /images/20220328/9cf8cb593b4c46e38a9efbc6aa6c9141.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70]: /images/20220328/ee472a369da94c8087a42030c414f8bc.png [https_blog.csdn.net_zeping891103_article_details_85769957]: https://blog.csdn.net/zeping891103/article/details/85769957 [20190109212925911.png]: /images/20220328/fdb1d49558954e5a803e783608feb4c6.png [https_www.python.org_downloads]: https://www.python.org/downloads/ [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 1]: /images/20220328/9529f8e92c2e4353a63d3a58359be830.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 2]: /images/20220328/177e8e18d5b54fd4bc6afd5eb6d48c0c.png [20190110215738327.png]: /images/20220328/d3c906e5a40b4eaf8b5f07f01da7db2d.png [20190110112056869.png]: /images/20220328/3a981c58096244d1a89d5bc9bba09ed2.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 3]: /images/20220328/beb670757751403685f2a49a556fb1cc.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 4]: /images/20220328/5788b5caf4f1442cb2f9b1d8b853bfcf.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 5]: /images/20220328/90f578a058c944d090e4e6f3d28da7f7.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 6]: /images/20220328/a2f76d951408413aa3114ad618811b34.png [https_www.crifan.com_react_native_ios_run_again_error_no_bundle_url_present]: https://www.crifan.com/react_native_ios_run_again_error_no_bundle_url_present/ [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 7]: /images/20220328/c015d173ea434af6bae79b4316b2bc0c.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 8]: /images/20220328/f6ef593e790f4e99adf975573e1af665.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 9]: /images/20220328/a98076aaef8c4af9bb649706680f8391.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 10]: /images/20220328/3545f61ffe9a46b682ce2f162f7ef845.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 11]: /images/20220328/38c72e1ce954415e90ed2ca3d1911aa7.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 12]: /images/20220328/d8b86eabc68443f8ad3ac1a12f6a2bb0.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 13]: /images/20220328/d40ea39a312c4ec292e5f8cd9bce2d4f.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 14]: /images/20220328/07383221b44c48d38674a01b973ff997.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 15]: /images/20220328/567920594fde4240a0606da057b0d0aa.png [https_stackoverflow.com_questions_47739777_android-studio-avd-emulator-process-finished-with-exit-code-1_47739865]: https://stackoverflow.com/questions/47739777/android-studio-avd-emulator-process-finished-with-exit-code-1/47739865 [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 16]: /images/20220328/caf01321b82f48b7b3cb04efcaf06cbb.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 17]: /images/20220328/a618ffc8ccdc4901b597edd2c5782b5c.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 18]: /images/20220328/6edc9a856b4849dd96614b1aaccbcf69.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 19]: https://img-blog.csdnimg.cn/20190211171938986.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2,size_16,color_FFFFFF,t_70 [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 20]: /images/20220328/5aa08381c73147a4a4447d4b938189ea.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 21]: https://img-blog.csdnimg.cn/20190301182636273.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2,size_16,color_FFFFFF,t_70 [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODE1NTk2_size_16_color_FFFFFF_t_70 22]: /images/20220328/b962276f0eb541248c85cfdebc7294b1.png
还没有评论,来说两句吧...