React Native02

602 阅读8分钟

一、自定义组件

RN中自定义组件跟React自定义组件是类似的,但是在使用RN基本组件的时候,要先引入

    import { View, Text, StyleSheet } from 'react-native'
  • RN中最外层需要用View组件包裹起来
  • 但凡视图中出现文本内容,都要使用Text组件包裹起来
  • RN定义样式的方式跟React不一样,RN是通过react-native的StyleSheet.create来创建的,通过键值对的形式来定义样式
    // 引入React的核心模块
    import React, { Component } from 'react'
    import { View, Text, StyleSheet } from 'react-native'
    
    // 创建并导出组件
    export default class App extends Component {
        render() {
            return (
                <View style={styles.container}>
                    <Text style={styles.txt}>你好,ReactNative!!</Text>
                </View>
            )
        }
    }
    
    // 样式要使用驼峰命名法,也不需要添加单位
    const styles = StyleSheet.create({
        container: {
            backgroundColor: '#ccc'  
        },
        txt1: {
            color: 'orange',
            fontSize: 24
        }
    })
    

二、View组件

View组件是一个容器组件,用来装载其它的组件,类似于div

  • 如果超出View组件的内容是不会显示的,如果想要显示超出的内容(滚动条形式显示)的话,需要配合ScrollView组件来使用。
    // 引入 React 的核心模块
    import React, { Component } from 'react'
    import { View, Text, StyleSheet } from 'react-native'
    
    // 创建并导出组件
    export default class App extends Component {
        render() {
            return (
                <View style={styles.container}>
                    <Text style={styles.txt1}>你好,ReactNative!!你好,ReactNative!!你好,ReactNative!!你好,ReactNative!!
                    你好,ReactNative!!你好,ReactNative!!你好,ReactNative!!你好,ReactNative!!你好,ReactNative!!
                    你好,ReactNative!!你好,ReactNative!!你好,ReactNative!!你好,ReactNative!!
                    </Text>
                </View>
            )
        }
    }
    
    const styles = StyleSheet.create({
        container: {
            width: 100,
            height: 100,
            backgroundColor: '#ccc'
        },
        txt1: {
            color: 'pink'
        }
    })

三、初步认识ScrollView组件

ScrollView组件是用来使超出View组件的内容显示的(以滚动条形式显示)

    // 引入 React 的核心模块
    import React, { Component } from 'react'
    import { View, Text, StyleSheet } from 'react-native'
    
    // 创建并导出组件
    export default class App extends Component {
        render() {
            return (
                <View style={styles.container}>
                    {/* ScrollView 默认是以垂直方向的,如果要使滚动条显示在水平方向,需要添加一个属性 horizontal */}
                    <ScrollView>
                        <Text style={styles.txt1}>你好,ReactNative!!你好,ReactNative!!你好,ReactNative!!你好,ReactNative!!
                        你好,ReactNative!!你好,ReactNative!!你好,ReactNative!!你好,ReactNative!!你好,ReactNative!!
                        你好,ReactNative!!你好,ReactNative!!你好,ReactNative!!你好,ReactNative!!
                        </Text>
                    </ScrollView>
                </View>
            )
        }
    }
    
    const styles = StyleSheet.create({
        container: {
            width: 100,
            height: 100,
            backgroundColor: '#ccc'
        },
        txt1: {
            color: 'pink'
        }
    })

四、RN获取屏幕的宽高及像素比

在RN中,我们是使用Dimensions组件来获取我们屏幕的宽高及像素比

    // 引入React的核心模块
    import React, { Component } from 'react'
    import { View, Text, Dimensions } from 'react-native'
    
    // 使用我们的Dimensions组件来获取屏幕宽高、像素比
    const { width, height, scale } = Dimensions.get('window')
    
    // 创建并导出组件
    export default class App extends Component {
        render() {
            return (
            // 这里采用的手机模拟器分辨率是1080*1920
                <View>
                    <Text>屏幕的宽度:{width}</Text>  // 360
                    <Text>屏幕的高度:{height}</Text> // 592
                    <Text>屏幕的像素比:{scale}</Text> // 3
                </View>
            )
        }
    }
  • 这里我们可以看到屏幕的宽度360跟分辨率1080的比例正好是我们的像素比3,说明一个像素块等于3倍分辨率

  • 细心的同学们会发现,那高度592跟分辨率比例不成3倍呀,这是为什么呢?请大家思考一下

  • 这是因为我们使用组件Dimensions获取到的宽高是屏幕的可视(可用)宽高

五、思考题

通过上面的讲解,请根据一下两个条件来编写代码

  • 1、书写一个满屏的盒子
  • 2、书写一条最细的线
    // 引入 React 的核心模块
    import React, { Component } from 'react'
    import { View, Text, StyleSheet, Dimensions } from 'react-native'
    
    // 根据 Dimensions 获取屏幕的宽高、像素比
    const { width, height, scale } from Dimensions.get('windos')
    
    // 创建并导出组件
    export default class App extends Component {
        render() {
            return (
                <View style={styles.container}>
                    <Text>屏幕的宽度:{width}</Text>
                    <Text>屏幕的高度:{height}</Text>
                    <Text>屏幕的像素比:{scale}</Text>
                    <View style={styles.line}></View>
                </View>
            )
        }
    }
    
    const styles = StyleSheet.create({
        container: {
            width,
            height,
            backgroundColor: '#ccc'
        },
        line: {
            height: 1/scale,
            backgrouncColor: 'pink'
        }
    })

这里的最细的线为什么要用1/scale呢?

  • 因为前面说了高度跟分辨率的比例是1:3,这里的1其实是3,所以除以像素比3可以得到1像素的分辨率,这才是最小的

六、Flex布局

6.1、display属性

  • display是用来设置组件的显示类型,它只支持 'flex' 和 'none'。默认值是 'flex'

6.2、flex属性

  • flex是一个正数,根据父盒子的大小来按比例分配其在父盒子中占据了多少,如果设置1,并且父盒子中只有一个子元素,那么子元素将平铺整个父盒子,如果设置1但是父盒子中不止一个子元素,那么怎么瓜分父盒子的空间呢?
  • 如果设置1并且父盒子中不止一个子元素,那么就根据所有子元素的flex值的和来将父盒子瓜分为多少份,然后再根据每一个子元素的flex值来分配其在父盒子中占据了多少

6.3、flexDirection属性

  • flexDirection属性决定我们主轴的方向,有五个值,分别是 'row', 'row-reverse', 'column', 'column-reverse', 默认值是 'column'.
  • row: 设置主轴为水平方向
  • row-reverse: 设置主轴为水平反向
  • column: 设置主轴为垂直方向
  • column-reverse: 设置主轴为垂直反向

6.4、justifyContent属性

  • justifyContent属性决定我们主轴上的对齐方式,有五个值,分别是 'flex-start', 'flex-end', 'center', 'space-between', 'space-around'.
  • flex-start: 如果主轴是水平方向,flex-start是左对齐; 如果主轴是垂直方向, flex-start是向上对齐。
  • flex-end: 如果主轴是水平方向,flex-end是右对齐; 如果主轴是垂直方向, flex-end是向下对齐。
  • center: 如果主轴是水平方向, center是水平居中; 如果主轴是垂直方向, center是垂直居中。
  • space-between: 如果主轴是水平方向, space-between是中间留白; 如果主轴是垂直方向, space-between是中间留白。
  • space-around: 如果主轴是水平方向, space-around是中间和两侧留白; 如果主轴是垂直方向, space-around是中间和两侧留白。

6.5、alignItem属性

  • alignItems属性决定我们交叉轴上的对其方式,有五个值,分别是 'flex-start', 'flex-end', 'center', 'stretch', 'baseline'.
  • flex-start:如果交叉轴是水平方向,flex-start是左对齐; 如果交叉轴是垂直方向, flex-start是向上对齐。
  • flex-end:如果交叉轴是水平方向,flex-end是右对齐; 如果交叉轴是垂直方向, flex-end是向下对齐。
  • center:如果交叉轴是水平方向,center是水平居中; 如果交叉轴是垂直方向, center是垂直居中。
  • stretch:如果交叉轴是水平方向, stretch是水平方向延伸; 如果交叉轴是垂直方向, stretch是垂直方向延伸。
  • baseline:如果交叉轴是水平方向, baseline是以水平方向上的文字底部为基线进行对齐;

七、Button组件

RN中用来显示按钮的组件 Button

官网:reactnative.cn/docs/button…

Button组件中比较重要的几个属性:

  • title:按钮内显示的文本
  • onPress:当按压按钮时绑定的事件
  • color:在IOS中表示文本的颜色,在Android中表示的是按钮的背景色

Button存在局限性,无法使用样式来对Button组件进行样式的修改,那怎么办呢?

这就引出了 TouchableOpacity 自定义组件

TouchableOpacity组件用于封装视图,使其可以正常的响应触摸操作

    import React, { Component } from 'react'
    import { View, Text, StyleSheet, Button, TouchableOpacity } from 'react-native'
    
    export default class App extends Component {
        constructor(props) {
            super(props)
            this.state = {
                num: 24
            }
        }
        handlePress() {
            this.setState({
                num: this.state.num + 1
            })
        }
        render() {
            return (
                <View>
                    <Text>{this.state.num}</Text>
                    {/* Button是无法使用样式来控制的 */}
                    <Button title="按钮的显示文本" onPress={this.handlePress.bind(this)} style={styles.btn}></Button>
                    
                    {/* TouchableOpacity可以使用样式来控制 */}
                    <TouchableOpacity onPress={this.handlePress.bind(this)} style={styles.btn}>
                        <Text>点击累加</Text>
                    </TouchableOpacity>
                </View>
            )
        }
    }
    
    const styles = StyleSheet.create({
        btn: {
            width: 100,
            height: 100,
            borderRadius: 50,
            color: 'pink',
        }
    })

八、Image组件

Image组件用来引入我们图片

  • Image有三种引入方式:

引入方式一:无需设置宽、高

    import React, { Component } from 'react'
    imoprt { View, Image } from 'react-native'
    
    import Img from '../res/logo.png'
    
    export default class App extends Component {
        render() {
            return (
                <View>
                    <Image source={Img}></Image>
                </View>
            )
        }
    }

引入方式二:无需设置宽、高

    import React, { Component } from 'react'
    import { View, Image } from 'react-native'
    
    export default class App extends Component {
        render() {
            return (
                <View>
                    <Image source={require('../res/logo.png')}></Image>
                </View>
            )
        }
    }

引入方式三:需要设置宽、高,不然图片不会显示

    import React, { Component } from 'react'
    import { View, Image, StyleSheet } from 'react-native'
    
    export default class App extends Component {
        render() {
            return (
                <View>
                    <Image source={{ uri: 'https://img11.360buyimg.com/babel/s380x300_jfs/t1/108103/4/5428/80278/5e39385eEdf8e1165/
                    33722fb26a351b83.jpg.webp'}} style={styles.img}></Image>
                </View>
            )
        }
    }
    
    const styles = StyleSheet.create({
        img: {
            width: 300,
            height: 150
        }
    })

九、WebView组件

WebView组件用于创建原生的WebView,可以用于访问一个网页

  • 通过给 WebView 的source属性的uri写入对应的网页地址,就可以在应用中直接打开页面
    import React, { Component } from 'react'
    import { WebView } from 'react-native'
    
    export default class App extends Component {
        render() {
            return (
                <WebView source={{ uri: 'https://m.jd.com/' }}></WebView>
            )
        }
    }