RN学习之我的第一个RN小例子

最近用点空余时间学习一下ReactNative,跟着教程做了一个小例子,做出的效果让我很吃惊,真的“很原生”!!!真的要加紧学习了,不然Andrdoid开发就将要失业咯。

 

讲讲我是怎么做这个小例子的。

 

1、先是搭建环境,步骤比较复杂,也会遇到很多坑,折腾两天才搭建好环境也是正常的,所以学习这个还是不能急躁哇。

ReactNative环境搭建。

 

2、写代码。对于我们Android来说,新手可以将代码写在index.android.js 这个文件里

 

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  TextInput,
  ScrollView,
  Image,
  TouchableWithoutFeedback,
  TouchableOpacity,
  Alert,
  ToastAndroid,
  TouchableHighlight
} from 'react-native';


/**
 *  获取屏幕宽高
 */
var Dimensions = require("Dimensions"); 
var {width,height} = Dimensions.get('window'); 


let pic = { //Map集合 key:value
      uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
};


export default class Demo1 extends Component {
	
	//js
	constructor(props){
		super(props);
		
		this.state = {  //有点类似Map集合,这里非要用state,state内部变量?
            images :[
				pic,
				require('./image/image1.jpg'),
				require('./image/image2.jpg'),
				require('./image/image3.jpg'),
				require('./image/image4.jpg'),
				require('./image/image5.jpg'),
				require('./image/image6.jpg')
			], 
            selectedImageIndex: 0,
            isNeedRun: true,
        };

        this._index = 0;// 当前正在显示的图片
        this._max = this.state.images.length;// 图片总数
		
	} 

	//js里面嵌入html,放在render里面
	render() {
    return (
      <View style={styles.container}>
	  
	  {/*导航*/}
		<View style={styles.topView}>
			<Text style={styles.topTitile}> 天猫超市</Text>
		</View>
		{/*纵向的ScrollView*/}
		<ScrollView>
			<View style={styles.headerView}>
					<View>
						{/*横向的ScrollView,淘宝轮播图*/}
						<TouchableOpacity onPress={() =>this.onBannerPressed()}  activeOpacity={0.9} >
						<ScrollView  
							ref='scrollView'
							horizontal={true}  
							showsHorizontalScrollIndicator={false}
							pagingEnabled={true}
							onMomentumScrollEnd={this.changeNumber.bind(this)}  //大括号里可以放js代码
							>
							
							<Image source={this.state.images[0]} style={{width: width, height: 160 ,marginTop:10}}/>   
							<Image source={this.state.images[1]} style={{width: width, height: 160 ,marginTop:10}}/>
							<Image source={this.state.images[2]} style={{width: width, height: 160 ,marginTop:10}}/>
							<Image source={this.state.images[3]} style={{width: width, height: 160 ,marginTop:10}}/>
							<Image source={this.state.images[4]} style={{width: width, height: 160 ,marginTop:10}}/>
							<Image source={this.state.images[5]} style={{width: width, height: 160 ,marginTop:10}}/>
							<Image source={this.state.images[6]} style={{width: width, height: 160 ,marginTop:10}}/>
						</ScrollView>
						</TouchableOpacity>
						
						<View style={styles.indicatorContainer}>
							<Text style={this.state.selectedImageIndex ==0?styles.active_indicator:styles.indicator}> •</Text>
							<Text style={this.state.selectedImageIndex ==1?styles.active_indicator:styles.indicator}> •</Text>
							<Text style={this.state.selectedImageIndex ==2?styles.active_indicator:styles.indicator}> •</Text>
							<Text style={this.state.selectedImageIndex ==3?styles.active_indicator:styles.indicator}> •</Text>
							<Text style={this.state.selectedImageIndex ==4?styles.active_indicator:styles.indicator}> •</Text>
							<Text style={this.state.selectedImageIndex ==5?styles.active_indicator:styles.indicator}> •</Text>
							<Text style={this.state.selectedImageIndex ==6?styles.active_indicator:styles.indicator}> •</Text>
						</View>
					
					</View>
					
					
				
					<TouchableWithoutFeedback onPress={() => this.onBannerPressed()}><Image source={pic} style={{width: width, height: 110 ,marginTop:10 }} /></TouchableWithoutFeedback>
					<TouchableWithoutFeedback onPress={() => this.onBannerPressed()}><Image source={require('./image/image1.jpg')} style={{width: width, height: 110 ,marginTop:10}} /></TouchableWithoutFeedback>
					<TouchableWithoutFeedback onPress={() => this.onBannerPressed()}><Image source={require('./image/image2.jpg')} style={{width: width, height: 110 ,marginTop:10}} /></TouchableWithoutFeedback>
					<TouchableWithoutFeedback onPress={() => this.onBannerPressed()}><Image source={require('./image/image3.jpg')} style={{width: width, height: 110 ,marginTop:10}} /></TouchableWithoutFeedback>
					<TouchableWithoutFeedback onPress={() => this.onBannerPressed()}><Image source={require('./image/image4.jpg')} style={{width: width, height: 110 ,marginTop:10}} /></TouchableWithoutFeedback>
					<TouchableWithoutFeedback onPress={() => this.onBannerPressed()}><Image source={require('./image/image5.jpg')} style={{width: width, height: 110 ,marginTop:10}} /></TouchableWithoutFeedback>
					<TouchableWithoutFeedback onPress={() => this.onBannerPressed()}><Image source={require('./image/image6.jpg')} style={{width: width, height: 110 ,marginTop:10}} /></TouchableWithoutFeedback>
				
			</View>
			
			{/*输入框*/}
			<View style={styles.inputView}>
				<TextInput  style={styles.textInputStyle}
					placeholder={"邮箱: "}
				
				/>
				<TextInput  style={styles.textInputStyle} 
					placeholder={"密码: "}
					secureTextEntry={true}
				/>
			</View>
			
			{/*按钮*/}
			<TouchableOpacity  activeOpacity={0.8} onPress={() => this.loginClicked()}>
			<View style={styles.btnView}>
				<Text style={styles.btnText} onPress={() => this.loginClicked()}>
					登  陆
				 </Text>
			</View>
			</TouchableOpacity>
		</ScrollView>
      </View>
    );
  }
  
  
	//js 
	
	//html里调用loginClicked加括号就会出现奇怪的问题
	loginClicked(){
	  //alert('我被点击了');
	  
	   Alert.alert('温馨提醒','确认登录?',[

            {text:'取消',onPress:()=>ToastAndroid.show('你点击了取消~',ToastAndroid.SHORT)},

            {text:'确定',onPress:()=>ToastAndroid.show('你点击了确定~',ToastAndroid.SHORT)}]);
	}
  
  	
	//手动滑动
	changeNumber(e){
		var e = e.nativeEvent;
		console.log(e);
		var scrolledX = e.contentOffset.x;
		var scrolledImageIndex = Math.round(scrolledX/width);
		this.setState({ //state赋值,属性默认有set方法。
			selectedImageIndex: scrolledImageIndex
		})
		//滑动对定时指示器的影响
		this._index = scrolledImageIndex;
	}
	
	//程序加载 组件装载完成,系统自己调
    componentDidMount(){
        this.startRunImage();
    }

   //自动轮播
   startRunImage(){
	    var scrollView = this.refs.scrollView;
		
        if(this._max <= 1){ // 只有一个则不启动定时任务
            return;
        }
        this._timer = setInterval(function () {
            this._index++;
            if(this._index >= this._max){
                this._index = 0;
            }
            scrollView.scrollTo({x:this._index * width},true);
            // 重置小圆点指示器
            this.refreshFocusIndicator();
        }.bind(this), 2000);
    }

	//刷新指示器
    refreshFocusIndicator(){
        this.setState({selectedImageIndex:this._index});
    }

	//程序退出
	 // 组件即将卸载
    componentWillUnmount(){
        clearInterval(this._timer);
    }

	onBannerPressed(){
        Alert.alert('温馨提醒','你点击了第'+(this._index+1)+'张图片',[

            {text:'取消',onPress:()=>ToastAndroid.show('你点击了取消~',ToastAndroid.SHORT)},

            {text:'确定',onPress:()=>ToastAndroid.show('你点击了确定~',ToastAndroid.SHORT)}]);
	}
  
}

const styles = StyleSheet.create({
  container: {
    flex: 1,      //表示 weight=1
	backgroundColor:'#f2f2f2'
  },
  topView:{
	  height:44,
	  backgroundColor:'#ff5400',
	  justifyContent:'center',
	  alignItems:'center'
  },
  topTitile:{
	  fontSize:20,
	  color:'white'
  },
  headerView:{
	  
	  
  },
  
  indicatorContainer:{
	  height:30,
	  backgroundColor:'rgba(0,0,0,0.1)',
	  position:'absolute',
	  width:width,
	  bottom:0,
	  flexDirection:'row',  //里面子控件的排列方式,水平排列
	  justifyContent:'center',
	  alignItems:'center'
	  
  },
 
  inputView:{
	  marginTop:10
  },
  textInputStyle:{
	  backgroundColor:'#fff',
	  height:44,
	  borderBottomColor:'#ddd',
	  borderBottomWidth:1,
	  paddingLeft:15,
	  paddingRight:15
  },
  
  btnView:{
	width:width-30,
	height:44,
	backgroundColor:'#ff5400',
	justifyContent:'center',
	alignItems:'center',
	marginTop:20,
	marginLeft:15,
	marginBottom:20
  },
  btnText:{
	color:'white',
	fontSize:16
  },
  
  //轮播图相关
   indicator:{
	  fontSize:38,
	  color:'white'
  },
  
  active_indicator:{
	  fontSize:38,
	  color:'#ff5400'
  }

});

AppRegistry.registerComponent('Demo1', () => Demo1);


3、运行效果:

 

 

 

 

 

 

完整项目地址:https://github.com/tomyZhou/react_native_simple_demo_android

 

<think>好的,我需要帮助用户了解鸿蒙React Native(HarmonyOS RN)的相关信息。首先,我要整理用户提供的引用内容,看看有哪些关键点可以提取。 根据引用[1],Fabric是React Native的渲染系统,负责处理组件信息并传递给原生OS进行渲染。这可能意味着在鸿蒙上,Fabric需要适配鸿蒙的原生组件。引用[2]提到ohos_react_native是基于React Native 0.72.5版本,由社区支持并在OpenHarmony-SIG开源,而Flutter也有支持,但这里重点在RN。引用[3]和[5]涉及环境安装和项目初始化,说明用户可能需要具体的开发步骤和版本信息。引用[4]提到图片缓存方案FastImage在鸿蒙使用C-API调用原生能力,这展示了如何利用鸿蒙特性优化性能。 接下来,我需要将这些信息组织成结构清晰的回答,涵盖框架定位、技术架构、开发环境、实践案例、注意事项等部分。同时,要确保使用正确的中文表达和LaTeX格式。例如,在提到版本号时,可能需要用$0.72.5$这样的格式,但根据用户指令,行内数学表达式应该用$...$,所以版本号可能不需要,但如果有技术术语需要强调,可以适当使用。不过这里可能不太需要数学表达式,但需要遵守格式要求。 用户的问题是关于鸿蒙RN的资料,所以需要提供官方资料、社区资源和开源项目链接。例如引用中的OpenHarmony-SIG仓库和ohos_react_native项目。同时,要提到环境搭建的步骤,如安装Node.js、DevEco Studio,使用npx命令初始化项目,如引用[5]中的命令示例。此外,混合开发的注意事项,如组件兼容性和性能优化,引用[4]中的FastImage案例可以作为例子。 还要生成相关问题,可能涉及开发环境配置、组件兼容性处理、性能优化方法、与Flutter的比较等。这些问题需要基于回答内容自然延伸,帮助用户进步探索。 需要确保回答真实可靠,引用正确来源。例如引用[2]提到ohos_react_native的版本和开源情况,引用[3]和[5]提供环境安装的具体步骤。同时,注意引用标识的正确添加,如每个引用末尾的[^n]。 最后,检查LaTeX语法是否正确,是否有不必要的数学表达式。例如,在提到版本号时,可能不需要数学格式,但如果有涉及变量或代码中的数字,可能需要使用$符号。但根据示例,代码部分用反引号包裹,所以可能不需要处理。确保行内公式正确,独立公式单独成段,但在这个回答中可能用不上独立公式。 总结,回答的结构应包括框架定位、技术架构、开发环境、实践案例、官方资料、注意事项,以及相关问题。确保每个部分的信息准确,引用正确,并符合格式要求。</think>### HarmonyOS React Native 开发框架解析 #### 1. **框架定位** HarmonyOS React Native(简称鸿蒙RN)是基于 React Native 0.72.5 版本的跨平台开发框架,由 OpenHarmony-SIG 社区支持并开源[^2]。它允许开发者使用 JavaScript/TypeScript 开发应用,并通过 Fabric 渲染系统将组件信息传递给鸿蒙原生系统完成渲染[^1]。 #### 2. **技术架构** - **渲染层**:鸿蒙RN通过 Fabric 组件渲染系统,将 React 组件转换为鸿蒙原生组件,例如使用 `FastImage` 组件调用鸿蒙的图片处理能力[^4]。 - **跨平台适配**:针对鸿蒙系统特性,通过 C-API 调用原生接口,优化性能与兼容性。 - **混合开发支持**:支持与 HarmonyOS 原生模块(如 UI 组件、系统服务)集成,实现渐进式开发[^3]。 #### 3. **开发环境配置** 1. **基础依赖**: - Node.js 16+、DevEco Studio、HarmonyOS SDK。 - 初始化项目命令: ```bash npx react-native@0.72.5 init AwesomeProject --version 0.72.5 [^5] ``` 2. **鸿蒙适配**:需配置 `ohos-react-native` 插件,并确保 `build.gradle` 中鸿蒙依赖项正确。 #### 4. **实践案例** - **图片加载优化**:使用 `FastImage` 组件替代默认 `Image`,通过鸿蒙原生能力提升加载性能。 - **混合页面开发**:在鸿蒙原生页面中嵌入 RN 组件,或反之,通过 `NativeModule` 实现双向通信。 #### 5. **官方资料与资源** - **开源仓库**: - [ohos_react_native](https://gitee.com/openatom-harmony/ohos_react_native)(OpenHarmony-SIG) - **文档参考**: - 《[HarmonyOS和React Native混合开发)之环境安装](https://developer.harmonyos.com)》[^3] #### 6. **注意事项** - **组件兼容性**:部分 React Native 第三方库需适配鸿蒙 API,例如导航库需依赖鸿蒙 `Router` 模块。 - **性能优化**:复杂动画建议使用鸿蒙原生能力(如 `ArkUI`)替代 RN 实现[^4]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值