1棺聊、了解目錄結構
2、頁面
2.1組件
2.2布局
2.3樣式
3、頁面跳轉
3.1RN頁面間跳轉
App.js //初始化路由 npm install react-native-deprecated-custom-components
安裝Navigator
import React, {Component} from 'react';
import Navigator from 'react-native-deprecated-custom-components';
import A from './src/A'
export default class App extends Component {
render() {
let defaultName='A';
let defaultComponent=A
return (
<Navigator.Navigator
initialRoute={{
name:defaultName,
component:defaultComponent
}}
renderScene={(route,navigator)=>{
let Component=route.component;
return(<Component {...route.params} navigator={navigator}/>);
}}
/>
);
}
}
A.js
import React,{ Component } from 'react';
import {
View,ScrollView,Text
} from 'react-native'
import B from './B'
export default class A extends Component{
//初始化函數(shù)
constructor(props){//舊版本getInitialState()
super(props)
this.state={//定義變量
id:2,
user:'Viknando',
userName:null
}
}
_pressBtn(){
const{navigator}=this.props;
const self=this;
if(navigator){
navigator.push({//頁面跳轉
name:'B',
component:B,
params:{
user:this.state.user,
id:this.state.id,
//將此方法作為參數(shù)傳到B中調用
getUserName:function(userName){
self.setState({
userName:userName
})
}
}
})
}
}
render(){
if(this.state.userName){
return(<View>
<Text></Text>
<Text></Text>
<Text>user:{JSON.stringify(this.state.userName)}</Text>
</View>)
}else{
return(
<ScrollView>
<Text></Text>
<Text></Text>
<Text onPress={this._pressBtn.bind(this)}>Hello!</Text>
<Text onPress={this._pressBtn.bind(this)}>Viknando!</Text>
</ScrollView>
)
}
}
}
B.js
import React,{ Component } from 'react';
import {
ScrollView,Text
} from 'react-native'
export default class B extends Component{
constructor(props){
super(props)
this.state={
id:null
}
}
_pressBtn(){
const{navigator}=this.props;
const USER_MODELS={
1:{name:'Domsting',age:'24'},
2:{name:'Viknando',age:'20'},
}
if(this.props.user){
let userNameModel=USER_MODELS[this.props.id];
this.props.getUserName(userNameModel)//B invoked fun of A
}
if(navigator){
navigator.pop();
}
}
render(){
return(
<ScrollView>
<Text></Text>
<Text></Text>
<Text>userId:{this.state.id}</Text>
<Text onPress={this._pressBtn.bind(this)}>author:{this.state.user}</Text>
</ScrollView>
)
}
componentDidMount(){
this.setState({
id:this.props.id,
user:this.props.user
})
}
}
3.2RN與原生頁面間跳轉
原生頁面->RN:
tv_jump_rn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
jumpToRN();
}
});
public void jumpToRN(){
Intent intent=new Intent(this,MainActivity.class);//跳轉的怎么是class?
startActivity(intent);
this.finish();
}
Q:跳轉的怎么是class?原來MainActivity繼承了ReactActivity谬运,從而跳轉到了RN頁面。
public class MainActivity extends ReactActivity {
/**
* Returns the name of the main component registered from JavaScript.
* This is used to schedule rendering of the component.
*/
@Override
protected String getMainComponentName() {
return "RNjsWithNative";
}
}
Q:這樣就跳轉了垦藏?我們得知道這幾點:
1梆暖、android工程中MainApplication聲明了ReactApplication,getPackages()返回了new MainReactPackage()掂骏,之后我們添加模塊也要添加Package,我這里添加了new JumpRP()
public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),new JumpRP()
);
}
@Override
protected String getJSMainModuleName() {
return "index";
}
};
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
@Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
}
}
2轰驳、MainActivity中getMainComponentName將我們定義的模塊名:RNjsWithNative返回給了RN,在入口文件我們注冊了RNjsWithNative對應的組件app弟灼,還記得AppRegistry.registerComponent('RNjsWithNative', () => app);
么级解?MainActivity與RN對應的app模塊才綁定在了一起
RN頁面->原生
RN頁面的點擊事件代碼是這樣的,startActivityFromJS方法是自定義的?"com.rnjswithnative.BActivity"是包名田绑?
<Text style={styles.welcome}
onPress={() => NativeModules.Native_Module.startActivityFromJS("com.rnjswithnative.BActivity", "this msg from RN")}>
Jump to NativePage!!!
</Text>
沒錯勤哗,就是這樣的,在android項目中我們新建了我們得知道這幾點:
1掩驱、JumpModule繼承了ReactContextBaseJavaModule芒划,定義了用@ReactMethod修飾的startActivityFromJS方法
@ReactMethod
public void startActivityFromJS(String name, String params){
try{
Activity currentActivity = getCurrentActivity();
if(null!=currentActivity){
Class toActivity = Class.forName(name);
Intent intent = new Intent(currentActivity,toActivity);
intent.putExtra("msg", params);
currentActivity.startActivity(intent);
}
}catch(Exception e){
throw new JSApplicationIllegalArgumentException(
"不能打開Activity : "+e.getMessage());
}
}
2冬竟、JumpRP 聲明了ReactPackage,new了JumpModule民逼,也添加到了MainApplication
public class JumpRP implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
return Arrays.<NativeModule>asList(new JumpModule(reactContext));
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
如果RN要向原生發(fā)消息泵殴,調用JumpModule里自己定義的方法就行。獻上這個??
可以開始敲代碼了拼苍,在代碼中學習
先來幾個小??吃一吃:先圖再代碼如何笑诅?
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
Image
} from 'react-native';
export default class image_demo extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to React Nativ!
</Text>
<Image source={{uri:'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=1104142377,1692686148&fm=27&gp=0.jpg'}} style={styles.imageStyle} />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
});
export default class App extends Component{
render(){
return(
<View style={styles.container}>
<View style={[styles.item,styles.center]}>
<Text style={styles.font}>酒店</Text>
</View>
<View style={[styles.item,styles.lineLeftRight]}>
<View style={[styles.center,styles.flex,styles.lineCenter]}>
<Text style={styles.font}>
海外酒店
</Text>
</View>
<View style={[styles.center,styles.flex]}>
<Text style={styles.font}>
特惠酒店
</Text>
</View>
</View>
<View style={styles.item}>
<View style={[styles.center,styles.flex,styles.lineCenter]}>
<Text style={styles.font}>
團購
</Text>
</View>
<View style={[styles.center,styles.flex]}>
<Text style={styles.font}>
客棧
</Text>
</View>
</View>
</View>
)
}
}
const styles = StyleSheet.create({
container:{
marginTop:20,
marginLeft:5,
marginRight:5,
borderRadius:5,
padding:2,
// borderColor:'blue',
// borderWidth:1,
flexDirection:'row',
backgroundColor:'#FF0067'
},
item:{
flex:1,
height:80
},
center:{
justifyContent:'center',
alignItems:'center'
},
font:{
color:'#fff',
fontSize:16,
fontWeight:'bold'
},
flex:{
flex:1
},
lineLeftRight:{
borderLeftWidth:1,
borderRightWidth:1,
borderColor:'#fff'
},
lineCenter:{
borderBottomWidth:1,
borderColor:'#fff'
}
});
var imgs = [ 'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=1104142377,1692686148&fm=27&gp=0.jpg',
'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=1104142377,1692686148&fm=27&gp=0.jpg',
'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=1104142377,1692686148&fm=27&gp=0.jpg'
];//需要自己重新賦值鏈接,
class MyImage extends Component{
constructor(props){
super(props);
var imgs=this.props.imgs;
this.state={
imgs:imgs,
count:0,
}
}
goNext(){
var count = this.state.count;
count++;
if(count<imgs.length){
this.setState({
count:count,
})
}else{
this.setState({
count:0,
})}
}
goPreView(){
var count = this.state.count;
count--;
if(count>=0){
this.setState({
count:count,
})
}else{
this.setState({
count:imgs.length-1,
})
}
}
render(){
return(
<View style={[styles.flex]}>
<View style={styles.image}>
<Image style={styles.img} source={{uri:this.state.imgs[this.state.count]}} resizeMode='contain'/>
</View>
<View style={styles.btns}>
<TouchableOpacity onPress={this.goPreView.bind(this)}>
<View style={styles.btn}>
<Text>preview</Text>
</View>
</TouchableOpacity>
<TouchableOpacity onPress={this.goNext.bind(this)}>
<View style={styles.btn}>
<Text>next</Text>
</View>
</TouchableOpacity>
</View>
</View>
)
}
}
export default class App extends Component{
render(){
return(
<View style={[styles.flex, {marginTop:40}]}>
<MyImage imgs={imgs}></MyImage>
</View>
);
}
}
var styles = StyleSheet.create({
flex:{
flex: 1,
alignItems:'center'
},
image:{
borderWidth:1,
width:300,
height:200,
borderRadius:5,
borderColor:'#ccc'
},
img:{
height:200,
width:300,
},
btns:{
flexDirection: 'row',
justifyContent: 'center',
marginTop:20
},
btn:{
width:60,
height:30,
borderColor: '#0089FF',
borderWidth: 1,
justifyContent: 'center',
alignItems:'center',
borderRadius:3,
marginRight:20,
},
});