美文网首页
React-Native学习笔记

React-Native学习笔记

作者: 手中的风信子 | 来源:发表于2018-10-17 22:36 被阅读11次

入门

Props属性

大多数组件在创建时就可以使用各种参数来进行定制。用于定制的这些参数就称为props(属性)

举个栗子:

//定义一个组件
class Greeting extends  Component{
    render() {
      return (
            <View style={{alignItems:'center'}}>
                <Text>Hello {this.props.name} </Text>
            </View>
      );
    };   
}
export default class HelloWorld extends Component{
    render() {
        let pic = {
            uri:"https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg"
        };
        return (
            <View style={{alignItems:'center'}}>
            <Image source={pic} style={{width: 200, height: 100}} ></Image>
                <Greeting name = 'Rex'></Greeting>
                <Greeting name = 'zhuxinlei'></Greeting>
                <Greeting name = 'ahah'></Greeting>
                <Blink name = '哈哈哈哈'></Blink>
            </View>
            );

    }
}

上面栗子中,Greeting组件的 name 就是一个属性,并在 <Text>Hello {this.props.name} </Text>组件中使用props属性集合中name这个属性。

如果在定义组件的时候没有定义name这个属性,则 <Text>Hello {this.props.name} </Text>不会输出有效的name属性值。

状态

我们使用两种数据来控制一个组件:propsstateprops是在父组件中指定,而且一经指定,在被指定的组件的生命周期中则不再改变。 对于需要改变的数据,我们需要使用state

1.在 constructor 中初始化state

2.然后在需要修改时调用setState方法

举个栗子:

假如我们需要制作一段不停闪烁的文字。文字内容本身在组件创建时就已经指定好了,所以文字内容应该是一个prop。而文字的显示或隐藏的状态(快速的显隐切换就产生了闪烁的效果)则是随着时间变化的,因此这一状态应该写到state中。

class  Blink extends Component{
    constructor(props) {
        super(props);
        this.state = { showText: true };        //定义一个 showText 状态赋值到this.state状态中
        this.state = { showOtherText: true};    //定义一个  showOtherText 状态 赋值到this.state状态中。 (此时this.state 中有两个状态)
    
        // 每1000毫秒对showText状态做一次取反操作
        setInterval(() => {
          this.setState(previousState => {
            return { showText: !previousState.showText };
          });
          this.setState( previousState => {
              return {showOtherText: this.state.showText}  //这里不能写showText,因为冒号后 只能拿到previousState或者使用this.state属性
          })
        }, 1000);
      }
    render(){
        // 根据当前showText的值决定是否显示text内容
        let display = ( (this.state.showText == this.state.showOtherText) && this.state.showText ) ? this.props.name : '';
        return(
            <Text>{display}</Text>
        );
    };
}

export default class HelloWorld extends Component{
    render() {
        let pic = {
            uri:"https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg"
        };
        return (
            <View style={{alignItems:'center'}}>
            <Image source={pic} style={{width: 200, height: 100}} ></Image>
                <Greeting name = 'Rex'></Greeting>
                <Greeting name = 'zhuxinlei'></Greeting>
                <Greeting name = 'ahah'></Greeting>
                <Blink name = '哈哈哈哈'></Blink>
            </View>
            );

    }
}

重点:

每次调用setState时,重新执行 render 方法重新渲染。这里我们使用定时器来不停调用setState,于是组件就会随着时间变化不停地重新渲染。

初学者要点

  • 一切界面变化都是状态state变化
  • state的修改必须通过setState()方法
    • this.state.likes = 100; // 这样的直接赋值修改无效!
    • setState 是一个 merge 合并操作,只修改指定属性,不影响其他属性
    • setState 是异步操作,修改不会马上生效

样式

使用StyleSheet.create来集中定义组件的样式

举个栗子

import React, { Component } from 'react';
import { AppRegistry, StyleSheet, Text, View } from 'react-native';

export default class LotsOfStyles extends Component {
  render() {
    return (
      <View>
        <Text style={styles.red}>just red</Text>
        <Text style={styles.bigblue}>just bigblue</Text>
        <Text style={[styles.bigblue, styles.red]}>bigblue, then red</Text>
        <Text style={[styles.red, styles.bigblue]}>red, then bigblue</Text>
      </View>
    );
  }
}

//自定义样式
const styles = StyleSheet.create({
    bigblue: {
        color: 'blue',
        fontWeight: 'bold',
        fontSize: 30,
      },
      red: {
          color: 'red',
      },
});

常见的做法是按顺序声明和使用style属性,以借鉴 CSS 中的“层叠”做法(即后声明的属性会覆盖先声明的同名属性)。

StyleSheet 详细说明

高度与宽度

组件的高度和宽度决定了其在屏幕上显示的尺寸。

举个例子:指定宽高

export default class HelloWorld extends Component {
  constructor(props) {
    super(props);
    this.state = {
    };
  }

  render() {
    return (
      <View>
        <View style={{width:50,height:50,backgroundColor: 'red'}}></View>
        <View style={{width:100,height:100,backgroundColor: 'skyblue'}}></View>
        <View style={{width:100,height:100,backgroundColor: 'blue'}}></View>
      </View>
    );
  }
}

弹性(Flex)宽高

在组件样式中使用flex可以使其在可利用的空间中动态地扩张或收缩。

一般而言我们会使用flex:1来指定某个组件扩张以撑满所有剩余的空间。

如果有多个并列的子组件使用了flex:1,则这些子组件会平分父容器中剩余的空间。如果这些并列的子组件的flex值不一样,则谁的值更大,谁占据剩余空间的比例就更大(即占据剩余空间的比等于并列组件间flex值的比)。

        // 试试去掉父View中的`flex: 1`,父View不再具有尺寸,因此子组件也无法再撑开。
        // 然后再用`height: 300`来代替父View的`flex: 1`,子组件的宽度为总宽度,高度组件平分
      <View style={{height:300}}>
        <View style={{width:50,height:50,backgroundColor: 'red'}}></View>
        <View style={{flex: 1,backgroundColor: 'skyblue'}}></View>
        <View style={{flex: 1,backgroundColor: 'blue'}}></View>
        <View style={{flex: 1,backgroundColor: 'yellow'}}></View>
      </View>

使用FlexBox布局

flexDirection

属性决定主轴的方向(即项目的排列方向)。

"column-reverse"| "column" | "row" | "row-reverse" ;

[站外图片上传中...(image-f13fdc-1539786979198)]

  • row :主轴为水平方向,起点在左端。

     render() {
        return (
          <View style={{flex: 1,flexDirection: 'row',}}>
            <View style={{width:50,height:50,backgroundColor:'red'}}></View>
            <View style={{width:50,height:50,backgroundColor:'blue'}}></View>
          </View>
        );
      }
    
屏幕快照 2018-10-17 22.16.51.png
  • row-reverse :主轴为水平方向,起点在右端。

    render() {
        return (
            //水平方向,起点在右端
          <View style={{flex: 1,flexDirection: 'row-reverse',}}>
            <View style={{width:50,height:50,backgroundColor:'red'}}></View>
            <View style={{width:50,height:50,backgroundColor:'blue'}}></View>
          </View>
        );
      }
    
屏幕快照 2018-10-17 22.18.34.png
  • column-reverse :主轴为垂直方向,起点在下沿。

    render() {
        return (
            //主轴为垂直方向,起点在最下端
          <View style={{flex: 1,flexDirection: 'column-reverse',}}>
            <View style={{width:50,height:50,backgroundColor:'red'}}></View>
            <View style={{width:50,height:50,backgroundColor:'blue'}}></View>
          </View>
        );
      }
    
屏幕快照 2018-10-17 22.23.52.png
  • column :主轴为垂直方向,起点在上沿
render() {
    return (
        //父视图是column属性,则子视图向下排列
      <View style={{flex: 1,flexDirection: 'column',}}>   
        <View style={{width:50,height:50,backgroundColor:'red'}}></View>
        <View style={{width:50,height:50,backgroundColor:'blue'}}></View>
      </View>
    );
  }
屏幕快照 2018-10-17 22.15.01.png

Justify Content

在组件的 style 中指定justifyContent可以决定其子元素沿着主轴排列方式。子元素是应该靠近主轴的起始端还是末尾段分布呢?亦或应该均匀分布?

对应的这些可选项有:

flex-start" | "flex-end" | "center" | "space-between" | "space-around" 
img
  • flex-start : 左对齐
 render() {
    return (
      <View style={{flex: 1,flexDirection: 'row', justifyContent:'flex-start'}}>
        <View style={{width:50,height:50,backgroundColor:'red'}}></View>
        <View style={{width:50,height:50,backgroundColor:'blue'}}></View>
      </View>
    );
  }
屏幕快照 2018-10-17 22.32.13.png
  • flex-end : 右对齐
render() {
    return (
        
      <View style={{flex: 1,flexDirection: 'row', justifyContent:'flex-end'}}>
        <View style={{width:50,height:50,backgroundColor:'red'}}></View>
        <View style={{width:50,height:50,backgroundColor:'blue'}}></View>
      </View>
    );
  }
屏幕快照 2018-10-17 22.38.09.png
  • center : 居中
render() {
    return (
      <View style={{flex: 1,flexDirection: 'row', justifyContent:'center'}}>
        <View style={{width:50,height:50,backgroundColor:'red'}}></View>
        <View style={{width:50,height:50,backgroundColor:'blue'}}></View>
      </View>
    );
  } 
[图片上传中...(屏幕快照 2018-10-17 22.42.07.png-75b45f-1539787624115-0)]
  • space-between : 两端对齐,项目之间的间隔都相等
 render() {
    return (
      <View style={{flex: 1,flexDirection: 'row', justifyContent:'space-between'}}>
        <View style={{width:50,height:50,backgroundColor:'red'}}></View>
        <View style={{width:50,height:50,backgroundColor:'blue'}}></View>
        <View style={{width:50,height:50,backgroundColor:'blue'}}></View>
        <View style={{width:50,height:50,backgroundColor:'blue'}}></View>
      </View>
    );
  }
屏幕快照 2018-10-17 22.42.07.png
  • space-around :每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍
render() {
    return (
      <View style={{flex: 1,flexDirection: 'row', justifyContent:'space-around'}}>
        <View style={{width:50,height:50,backgroundColor:'red'}}></View>
        <View style={{width:50,height:50,backgroundColor:'blue'}}></View>
        <View style={{width:50,height:50,backgroundColor:'blue'}}></View>
        <View style={{width:50,height:50,backgroundColor:'blue'}}></View>
      </View>
    );
  }
屏幕快照 2018-10-17 22.43.22.png

Align Items

在组件的 style 中指定alignItems可以决定其子元素沿着次轴(与主轴垂直的轴,比如若主轴方向为row,则次轴方向为column)的对齐方式。子元素是应该靠近次轴的起始端还是末尾段分布呢?亦或应该均匀分布?对应的这些可选项有:flex-startcenterflex-end以及stretch

"flex-start" | "flex-end" | "center" | "stretch" | "baseline"

注意:要使stretch选项生效的话,子元素在次轴方向上不能有固定的尺寸。以下面的代码为例:只有将子元素样式中的width: 50去掉之后,alignItems: 'stretch'才能生效。

图片
  • flex-start:交叉轴的起点对齐。
  • flex-end:交叉轴的终点对齐。
  • center:交叉轴的中点对齐。
  • baseline: 项目的第一行文字的基线对齐。
  • stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。

举个例子:

render() {
    return (
     <View style={{
        flex: 1,
        flexDirection: 'column', //主轴方向
        justifyContent:'flex-start', //子元素沿着主轴的对齐方式
        alignItems: 'center', //子元素沿着次轴的排列方式-交叉轴的起点对齐
     }}>

     <View style={{width: 50,height: 50,backgroundColor:'red'}}></View>
     <View style={{width:50,height:50,backgroundColor: 'blue'}}></View>
     <View style={{width:50,height:50,backgroundColor: 'yellow'}}></View>
     <View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />  
     </View>
    );
  }
屏幕快照 2018-10-18 22.30.36.png

总结:

当主轴的方向是 row横向时

  • justifyContent :主轴决定子元素左右的位置。flex-start"(最左) flex-end(最右)center(居中)space-between( 两端对齐) ,space-around (每个项目两侧的间隔相等)
  • alignItems:次轴 决定子元素上下的位置。 flex-start(最上) flex-end (最下) center(居中)

当主轴的方向是 column纵向时

  • justifyContent: 主轴决定子元素上下的位置. flex-start"(最上) flex-end(最下)center(居中)space-between( 两端对齐)
  • alignItems:次轴 决定子元素左右的位置。flex-start(最左) flex-end (最右) center(居中)

举个例子:

 return (
     <View style={{
        flex: 1,
        flexDirection: 'row', //主轴方向为横向
        justifyContent:'flex-start', //子元素沿着主轴的对齐方式,即决定左右位置。 左
        alignItems: 'center', //子元素沿着次轴的排列方式-交叉轴的起点对齐。 即决定上下位置。中
     }}>

     <View style={{width: 50,height: 50,backgroundColor:'red'}}></View>
     <View style={{width:50,height:50,backgroundColor: 'blue'}}></View>
     <View style={{width:50,height:50,backgroundColor: 'yellow'}}></View>
     <View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />  
     </View>
    );
  }
屏幕快照 2018-10-18 22.37.58.png
return (
     <View style={{
        flex: 1,
        flexDirection: 'column', //主轴方向为纵向
        justifyContent:'flex-start', //子元素沿着主轴的对齐方式  上
        alignItems: 'center', //子元素沿着次轴的排列方式-交叉轴的起点对齐  中
     }}>

     <View style={{width: 50,height: 50,backgroundColor:'red'}}></View>
     <View style={{width:50,height:50,backgroundColor: 'blue'}}></View>
     <View style={{width:50,height:50,backgroundColor: 'yellow'}}></View>
     <View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />  
     </View>
    );
  }
屏幕快照 2018-10-18 22.42.16.png

处理触摸事件

直接上代码:

import React, { Component } from 'react';
import { View, Text,Button,Alert ,AppRegistry,StyleSheet} from 'react-native';

export default class HelloWorld extends Component {
  constructor(props) {
    super(props);
    this.state = {
    };
  }

  //定义一个方法
  _onPressButton(){
      //提示方法 
      Alert.alert(
          "alert title",
          "alert message",
        [
            {text:'OK', onPress: ()=> console.log("点击了OK")},
            {text:'cancel', onPress: ()=> console.log("点了cancel")}
        ]
      );
  }

  render() {
    return (
      <View style={styles.container}>
        <View style={styles.buttonContainer}>
            <Button
                onPress={this._onPressButton}
                title='pressMe'
            ></Button>
        </View>

        <View style={styles.buttonContainer}>
            <Button
                onPress = {this._onPressButton}
                title = 'Press Me'
                color='#841584'
            ></Button>
        </View>


        <View style={styles.alternativeLayoutbuttonContainer}>
            <Button
                onPress = {this._onPressButton}
                title = 'This looks great!'
                
            ></Button>
            <Button
                onPress = {this._onPressButton}
                title = "OK"
                color = "#841584"
            ></Button>
        </View>
      </View>
       

    );
  }
}

//定义样式
const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
    },
    buttonContainer:{
       margin: 20,  //同时设置四个外边距
       backgroundColor:'yellow'
    },
    alternativeLayoutbuttonContainer:{
        margin:20,
        flexDirection: 'row',
        justifyContent: 'space-between',
        
    }
})

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

Touchable 系列组件

  • 一般来说,你可以使用TouchableHighlight来制作按钮或者链接。注意此组件的背景会在用户手指按下时变暗
  • TouchableOpacity会在用户手指按下时降低按钮的透明度,而不会改变背景的颜色。
  • 如果你想在处理点击事件的同时不显示任何视觉反馈,则需要使用TouchableWithoutFeedback

某些场景中你可能需要检测用户是否进行了长按操作。可以在上面列出的任意组件中使用onLongPress属性来实现。

举个例子:


import React, { Component } from 'react';
import { View, Text ,Button,AppRegistry,Alert,Platform,StyleSheet,TouchableHighlight,TouchableOpacity,TouchableNativeFeedback,TouchableWithoutFeedback} from 'react-native';

export default class HelloWorld extends Component {
  constructor(props) {
    super(props);
    this.state = {
    };
  }

  //点击方法
  _onPressButton(){
      Alert.alert(
          '温馨提示',
          'you tapped the button!',
          [
              {text:'确定',onPress: () => console.log("点击了确定") },
              {text:'取消', onPress: () => console.log("点击了取消")},
          ]
      )
  }

  _onLongPressButton(){
      Alert.alert(
          'titile',
          'you long tapped the button!',
          [
            {text:'确定',onPress: () => console.log("点击了确定")},
            {text:'取消',onPress: () => console.log("点击了取消")},
          ]
      )
  }

  render() {
     <View style={styles.container}>
        {/* //点击后高亮 */}
        <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>
        
       <TouchableNativeFeedback 
       onPress={this._onPressButton} 
       backgroundColor={Platform.OS === 'android'? TouchableNativeFeedback.SelectableBackground() : '' }>
        <View style={styles.button}>
            <Text style={styles.buttonText}> TouchableNativeFeedback </Text>
        </View>
       </TouchableNativeFeedback> 
        {/* //点击后无反馈 */}
       <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>
    );
  }
}

const styles = StyleSheet.create({
      container:{
          paddingTop: 60,
          alignItems: 'center',
      },
      button:{
          marginBottom: 30,
          width: 260,
          alignItems: 'center',
          backgroundColor: '#2196F3',
          borderRadius:5
      },
      buttonText: {
          padding:20,
          color: 'white'
      }
})

AppRegistry.registerComponent('HelloWorld',() => HelloWorld)
屏幕快照 2018-10-19 11.20.42.png

StyleSheet 详细说明

var styles = StyleSheet.create({    

base: {width:38,height:38},   

background:{backgroundColor:'#222'}   

active:{borderWidth:2,borderColor:'#00ff00'}

});

Text style={styles.base} /

Text style={{styles.base, styles.background}} /

Text style={{styles.base, this.state.active && styles.active}} /

backfaceVisibility:visible|hidden;属性定义当元素不面向屏幕时是否可见

backgroundColor:背景色

transform

transformMatrix

定位

position:定位:相对定位(absolute),绝对定位(relative) 默认情况下使用的是相对定位

top:上

bottom:下

left:左

right:右

图像变换

scaleX :水平方向缩放

scaleY :垂直方向缩放

rotation :旋转

translateX :水平方向平移

translateY :水平方向平移

阴影

shadowColor

shadowOffset

shadowOpacity

shadowRadius

图片相关属性

resizeMode:enum('cover','contain','stretch') contain是指无论如何图片都包含在指定区域内,假设设置的宽度高度比图片大,则图片居中显示,否则,图片等比缩小显示

overflow:enum('visible','hidden')

tintColor:着色,rgb字符串类型

opacity:透明度
    

字体相关属性

color:字体颜色

fontFamily:字体族

fontSize:字体大小

fontStyle:字体样式,正常,倾斜,值为enum('normal','italic')

fontWeight:字体粗细,值为enum('normal','bold','100','200'...,'900')

letterSpacing:字符间隔

lineHeight:行高

textAlign:字体对齐方式,值为enum('auto','left','right','center','justify')

textDecorationColor:貌似没效果,修饰的线的颜色

textDecorationLine:貌似没效果,字体修饰,上划线,下划线,删除线,无修饰,值为enum("none",'underline','line-through','underline line-through')

textDecorationStyle:enum("solid",'double','dotted','dashed')貌似没效果,修饰的线的类型

writingDirection:enum("auto",'ltr','rtl')不知道什么属性,写作方向?从左到右?从右到左?

边框相关

borderStyle:边框样式

borderWidth:所有边框宽度

borderTopWidth:顶部边框宽度

borderBottomWidth:底部边框宽度

borderLeftWidth:左边边框宽度

borderRightWidth:右边框宽度

borderColor:边框颜色

borderTopColor:顶部边框颜色

borderBottomColor:底部边框颜色

borderLeftColor:左边边框颜色

borderRightColor:右边边框颜色

边框圆角

borderRadius

borderBottomLeftRadius

borderBottomRightRadius

borderTopLeftRadius

borderTopRightRadius

Flex布局相关

flex:number

flexDirection: enum('row','column','row-reverse','column-reverse') 属性决定主轴的方向(即项目的排列方向)。

flexWrap:enum('wrap','nowrap','wrap-reverse') 默认情况下,项目都排在一条线(又称"轴线")上。flex-wrap属性定义,如果一条轴线排不下,如何换行。

alignItems:enum('flex-start','flex-end','center','stretch') 属性定义项目在交叉轴上如何对齐。

alignSelf:enum('auto','flex-start','flex-end','center','stretch') 属性允许单个项目有与其他项目不一样的对齐方式,可覆盖

justifyContent:enum('flex-start','flex-end','center','space-between','space-around') 属性定义了项目在主轴上的对齐方式。

Flex 布局教程:语法篇 Flex 布局教程:实例篇

宽高

width

height

外边距:

marginTop:上

marginBottom:下

marginLeft:左

marginRight:右

margin:相当于同时设置四个

marginVertical:相当于同时设置marginTop和marginBottom

marginHorizontal:相当于同时设置marginLeft和marginRight

内边距

paddingTop:上

paddingBottom:下

paddingLeft:左

paddingRight:右

padding:相当于同时设置四个

paddingVertical:相当于同时设置paddingTop和paddingBottom

paddingHorizontal:相当于同时设置paddingLeft和paddingRight

相关文章

  • React-Native 学习笔记 - 使用FlatList加载

    React-Native 学习笔记 - 使用FlastList加载网络数据 声明变量 网络请求方法 加载等待的Vi...

  • React Native资料

    React-Native学习指南 Awesome React-Native系列 教程 react-native 官...

  • React Native资料

    React-Native学习指南 Awesome React-Native系列 教程 react-native 官...

  • React-Native学习笔记

    入门 Props属性 大多数组件在创建时就可以使用各种参数来进行定制。用于定制的这些参数就称为props(属性) ...

  • react-native学习笔记

    注:本文主要用于作者记录一些零散的知识,写得相对简洁,仅供作者本人理解使用 react-native执行过程 首先...

  • React-Native 学习笔记

    React-Native 学习笔记 1.props(属性)大多数组件在创建的时候就可以使用各种参数来进行定制,用于...

  • React-native 学习笔记

    一 基础知识 需要掌握的语法 export default 和 export 相同与区别? 相同点:均可用于导出常...

  • React-Native学习笔记

    RN笔记 一. 常用命令 比如我们希望查看RN的所有历史版本,可以在命令行中输入: npm view react-...

  • React学习资源

    github地址 React-Native学习指南 本指南汇集React-Native各类学习资源,给大家提供便利...

  • ReactNative学习——环境搭建

    React-Native学习 React-Native中文官网:http://reactnative.cn/doc...

网友评论

      本文标题:React-Native学习笔记

      本文链接:https://www.haomeiwen.com/subject/nxydzftx.html