react native导航器

react navigation学习(正在学习中,逐步更新)

1.     delete node_modules and package-lock.json
2.     npm install
3.     npm install --save react-navigation
4.     npm install --save react-native-gesture-handler
5.     react-native link

react navigation学习(正在学习中,逐步更新)

解决办法如链接:https://stackoverflow.com/questions/53367195/invariant-violation-the-navigation-prop-is-missing-for-this-navigator

  • demo1:创建一个 stack navigator

效果图如右图所示react navigation学习(正在学习中,逐步更新)点击按钮go Details Screen后跳转新页面react navigation学习(正在学习中,逐步更新)

项目文件夹如右图所示:react navigation学习(正在学习中,逐步更新)

1.新建一个文件夹src,在src内新建config和screens文件夹,config内新建route.js文件用来放置配置代码,screens内放置页面代码

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 { createStackNavigator,createAppContainer } from "react-navigation";
// 引入页面组件
import Home from '../screens/Home'
import Details from '../screens/Details'
// 配置路由
const AppNavigator = createStackNavigator({
  Home: Home,
  Details: Details
});
const Route = createAppContainer(AppNavigator);
export default Route;

Home.js

import React, { Component } from 'react';
import { View, Text, Button } from 'react-native';
const styles = {
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center'
  }
}
class Home extends Component {
  static navigationOptions = {
    // 设置 title
    title: "首页"
  };
  render() {
    return (
      <View style={styles.container}>
        <Text>Home Screen</Text>
        <Button
          title="go Details Screen"
          // 路由跳转
          onPress={() => this.props.navigation.push("Details")}
        />
      </View>
    );
  }
}
export default Home

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 {
  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

由上面的代码可知:

如果你处在堆栈深处,上面有多个页面,此时你想要将上面所有的页面都销毁,并返回第一个页面。 在这种情况下,要回到` Home `,可以使用` navigate('Home') `(而不是` push `! 尝试一下,看看有什么不同)。 另一个选择是` navigation.popToTop() `,它可以返回到堆栈中的第一个页面。

每次调用 ` push ` 时, 我们会向导航堆栈中添加新路由。 当你调用 ` navigate ` 时, 它首先尝试查找具有该名称的现有路由, 并且只有在堆栈上没有一个新路由时才会推送该路由。

this.props.navigation.goBack()实现返回

  • 将上述代码在android上运行时,遇到如下问题Could not connect to development server

react navigation学习(正在学习中,逐步更新)

解决方法,利用Android Studio打开当前项目的MainActivity.java文件,进行如下修改

在合适位置加上下面两段代码:

import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.ReactRootView;
import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;
    @Override
    protected ReactActivityDelegate createReactActivityDelegate() {
        return new ReactActivityDelegate(this, getMainComponentName()) {
            @Override
            protected ReactRootView createRootView() {
               return new RNGestureHandlerEnabledRootView(MainActivity.this);
            }
         };
    }

完整代码示例

package com.awesomeproject;

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 {

    /**
     * Returns the name of the main component registered from JavaScript.
     * This is used to schedule rendering of the component.
     */
    @Override
    protected String getMainComponentName() {
        return "AwesomeProject";
    }
    @Override
    protected ReactActivityDelegate createReactActivityDelegate() {
        return new ReactActivityDelegate(this, getMainComponentName()) {
            @Override
            protected ReactRootView createRootView() {
               return new RNGestureHandlerEnabledRootView(MainActivity.this);
            }
         };
    }
}

上述问题成功解决react navigation学习(正在学习中,逐步更新)

  • demo2传递参数给路由

1.在路由中传递

=> this.props.navigation.navigate("Details",{
            itemId: 86,
            otherParam: 'anything you want here'

2.接受路由的两种方法

const itemId = this.props.navigation.getParam('itemId', 'NO-ID');

const otherParam = this.props.navigation.state.params.otherParam;

3.

3.1设置标题栏显示的标题

页面组件navigationOptions,title这个属性用于设置标题栏的标题

3.2在标题中使用参数
在navigationOptions中使用this.props会报错,应该用{navigation> navigationOptions,screenProps}的对象调用它,再通过<code> navigation.state.params从navigation中获取参数

3.3使用setParams更新navigationOptions

<Button

title="Update the title"

onPress={() => this.props.navigation.setParams({title:'使用setParams更新navigationOptions'})}

/>

3.4调整标题样式
定制标题样式时有三个关键属性:headerStyle、headerTintColor和headerTitleStyle。

headerStyle:一个应用于 header 的最外层 View 的 样式对象, 如果你设置 backgroundColor ,他就是header 的颜色。
headerTintColor:返回按钮和标题都使用这个属性作为它们的颜色。 
headerTitleStyle:如果我们想为标题定制fontFamily,fontWeight和其他Text样式属性,我们可以用它来完成。

如下所示,在某个页面可以实现对title的样式设定

static navigationOptions = {
    // 设置 title
    title: "首页",
    headerStyle: {
      backgroundColor:'#010101',
    },
    headerTintColor:'#fff',
    headerTintStyle:{
      fontWeight:'bold'
    }
  };

3.5跨页面共享通用的navigationOptions

设置每一个页面的title,只需要在配置文件route.js中设置

const AppNavigator = createStackNavigator({
    Home: Home,
    Details: Details
  },
  {
    initialRouteName: 'Home',
    defaultNavigationOptions: {
      headerStyle: {
        backgroundColor: '#010101',
      },
      headerTintColor: '#fff',
      headerTitleStyle: {
        fontWeight: 'bold',
      },
    },
  }
);

4.完整代码(App.js如上所示,就不粘贴)

route.js

import { createStackNavigator,createAppContainer } from "react-navigation";
// 引入页面组件
import Home from '../screens/Home'
import Details from '../screens/Details'
// 配置路由
const AppNavigator = createStackNavigator({
    Home: Home,
    Details: Details
  },
  {
    initialRouteName: 'Home',
    defaultNavigationOptions: {
      headerStyle: {
        backgroundColor: '#010101',
      },
      headerTintColor: '#fff',
      headerTitleStyle: {
        fontWeight: 'bold',
      },
    },
    // navigationOptions: {
    //   tabBarLabel: 'Home!',
    // },
  }
);
const Route = createAppContainer(AppNavigator);
export default Route;

Home.js

import React, { Component } from 'react';
import { View, Text, Button, Image } from 'react-native';
class LogoTitle extends Component {
  render() {
    return (
      <View style={{flexDirection: 'row',justifyContent: 'flex-start',alignItems: 'flex-start'}}>
        <Image source={require('../img/preview.jpg')} 
          style={{ width: 30, height: 30 }} />
      </View>
    );
  }
}
class Home extends Component {
  static navigationOptions = {
    // 设置 title
    // title: "首页",
    headerTitle: "首页",
    headerLeft: <LogoTitle />,
    headerRight: (
      <Button
        onPress={() => alert('This is a button!')}
        title="Info"
        color="#fff"
      />
    ),
    // 设置 title 样式
    // headerStyle: {
    //   backgroundColor:'#010101',
    // },
    // headerTintColor:'#fff',
    // headerTintStyle:{
    //   fontWeight:'bold'
    // }
  };
  render() {
    return (
      <View>
        <Text>Home Screen</Text>
        <Button
          title="go Details Screen"
          // 路由跳转
          onPress={() => this.props.navigation.navigate("Details",{
            itemId: 86,
            title: 'Detail Page',
            otherParam: 'other'
          })}
        />
      </View>
    );
  }
}
export default Home

Details.js

import React, { Component } from 'react';
import { View, Text, Button } from 'react-native';
class Details extends Component {
  static navigationOptions = ({ navigation }) => {
    return {
      // 在标题中使用参数
      // title: navigation.getParam('title', 'Details Screen title'),
      title: navigation.state.params.title,
      headerRight: (
        <Button
          onPress={() =>navigation.goBack()}
          title="return home"
          color="#fff"
        />
      ),
    }
  };
  render() {
    const itemId = this.props.navigation.getParam('itemId', 'NO-ID');
    const otherParam = this.props.navigation.state.params.otherParam;
    return (
      <View>
        <Text>Details Screen</Text>
        <Button
          title="Go to Home"
          onPress={() => this.props.navigation.navigate('Home')}
        />
        <Button
          title="Go back"
          onPress={() => this.props.navigation.goBack()}
        />
        <Button
          title="Update the title"
          onPress={() => this.props.navigation.setParams({title:'使用setParams更新navigationOptions'})}
        />
        <Text>查看传参-----itemId:{itemId},otherParam:{otherParam}</Text>
      </View>
    );
  }
}
export default Details
  • demo3
  • demo4
  • demo5

 

 

相关文章: