美文网首页
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学习笔记

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