zoukankan      html  css  js  c++  java
  • ReactNative学习笔记(二)基础进阶

    一个最简单的HelloWorld页面

    先不多解释,直接上代码:

    import React, { Component } from 'react';
    import {AppRegistry, StyleSheet, Text, View} from 'react-native';
    
    export default class helloworldComponent extends Component
    {
    	render()
    	{
    		return (
    			<View style={styles.container}>
    				<Text style={styles.welcome}>Hello World!</Text>
    			</View>
    		);
    	}
    }
    
    const styles = StyleSheet.create(
    {
    	container:
    	{
    		flex: 1,
    		justifyContent: 'center',
    		alignItems: 'center',
    		backgroundColor: '#F5FCFF',
    	},
    	welcome:
    	{
    		fontSize: 20,
    		textAlign: 'center',
    		margin: 10,
    	}
    });
    
    // 这句话就相当于Java里面的main函数,不用特别深入了解,知道即可
    // 第一个参数的'helloworld'必须跟你的项目名一样
    AppRegistry.registerComponent('helloworld', () => helloworldComponent);
    

    官方推荐使用ES6语法,不熟悉ES6的同学可能看起来感觉这完全不是JS代码,可以先看看这篇文章熟悉一下区别:

    react-react-native-的es5-es6写法对照表

    对于Android平台而言,index.android.js就是整个项目的入口,AppRegistry.registerComponent则是入口中的main函数。我一般习惯index.android.js中只简单的写两三行代码,其它的以组件的形式加载进来:

    import React, { Component } from 'react';
    import { AppRegistry } from 'react-native';
    
    import MainPage from './views/MainPage';
    
    // 注意,这里用引号括起来的'helloworld'必须和你init创建的项目名一致
    AppRegistry.registerComponent('helloworld', () => MainPage);
    

    JSX语法

    React.js基础的话可能会很熟悉这个,我在学习ReactNative的时候没有接触过React.js,所以有些吃亏。

    JSX可以看做是内嵌在JS中的一段xml代码,不需要引号包裹,放在这个里面:render(){ return (JSX);}{}表示里面是一个变量或者表达式,和jsp的${}类似。

    注意每个render里面返回的XML根节点只能是一个,像下面这样的写法是错误的:

    render()
    {
    	return (
    		<Text>Hello World!</Text>
    		<Text>Hello World!</Text>
    	);
    }
    

    只能另外用一个组件把它包裹,比如<View>

    render()
    {
    	return (
    		<View>
    			<Text>Hello World!</Text>
    			<Text>Hello World!</Text>
    		</View>
    	);
    }
    

    动态拼接JSX

    因为JSX不是普通的字符串,我们没法像拼接字符串一样拼接它,但还是有办法的。JSX里面可以随意内嵌表达式:

    class TestComponent extends Component
    {
    	constructor(props)
    	{
    		super(props);
    		this.list = ['张三', '李四', '王二麻子', '小茗同学'];
    	}
    	render()
    	{
    		return (
    			<View style={{flex:1}}>
    				<Text>你好啊</Text>
    				{this.list.map((item, idx) => <Text key={'idx_'+idx}>{item}</Text>)}
    				<Image source={require('./image/logo.png')}/>
    			</View>
    		);
    	}
    }
    

    再复杂一点的还可以层层嵌套,代码多了则可以把遍历的代码单独写到一个方法里面然后调用,比如:

    class TestComponent extends Component
    {
    	constructor(props)
    	{
    		super(props);
    		this.list = ['张三', '李四', '王二麻子', '小茗同学'];
    	}
    	renderList(list)
    	{
    		return list.map((item, idx) =>
    		{
    			return (<Text key={'idx_'+idx}>{item}</Text>);
    		});
    	}
    	render()
    	{
    		return (
    			<View style={{flex:1}}>
    				<Text>你好啊</Text>
    				{this.renderList(this.list)}
    				<Image source={require('./image/logo.png')}/>
    			</View>
    		);
    	}
    }
    

    样式篇

    样式的写法

    样式可以直接写在style上面:

    <Text style={{color: 'red', fontSize: 16}} />
    

    也可以像css一样先单独定义好再引用,不过和css还是有很大差别的:

    var styles = StyleSheet.create({
      btn: {
         38,
        height: 38,
      },
      background: {
        backgroundColor: '#222222',
      },
      active: {
        borderWidth: 2,
        borderColor: '#00ff00',
      }
    });
    

    然后这样写:

    <Text style={styles.btn} /> // 单个class
    <Text style={[styles.btn, styles.active]} /> // 多个class
    <Text style={[styles.btn, {color: 'red'}]} /> // class与style混写
    

    注意事项:

    • 样式写法采用的是JSON格式;
    • 字符串属性必须加引号;
    • 大小全部没有px,纯数字;
    • 采用驼峰式命名,不是中划线;

    直接操作某个元素

    可以使用ref给元素实现类似HTML中的id的效果,即this.refs[id]document.getElementById(id)类似:

    render()
    {
    	return (
    		<View ref="btn" style={{ 100, height: 100}}/>
    	);
    }
    componentDidMount()
    {
    	// 组件显示完毕给它设置红色边框效果
    	this.refs['btn'].setNativeProps
    	({
    		style: {borderColor: 'red', borderWidth: 5}
    	});
    }
    

    当然,一般推荐使用state来修改界面,除非你对性能特别关注才用上述方法。

    已知setNativeProps无法修改Imagesource,这应该是个bug。

    图片加载

    加载本地图片

    官网推荐使用require加载图片,路径就是相对于js的相对路径,这种方式可以自动设置宽高度:

    <Image source={require('./images/check.png')} />
    

    虽然这种方式有很多优点,但是带来了一个致命的缺点:就是图片路径无法动态指定,比如下面这个例子,如果有100种状态需要判断,难道要写100个if else

    // 正确
    <Image source={require('./my-icon.png')} />
    
    // 错误
    var icon = this.props.active ? 'my-icon-active' : 'my-icon-inactive';
    <Image source={require('./' + icon + '.png')} />
    
    // 正确
    var icon = this.props.active ? require('./my-icon-active.png') : require('./my-icon-inactive.png');
    <Image source={icon} />
    

    目前还没有找到这个问题的有效解决方法。

    加载app资源图片

    加载已经打包到App中的图片资源(通过Xcode的asset类目或者Android的drawable文件夹打包):

    假设有这样一个文件:androidappsrcmain esdrawable-hdpiic_launcher.png,那么加载时可以直接这样,注意不需要.png后缀,而且必须手动指定宽高度,否则默认是0*0

    <Image source={{uri: 'ic_launcher'}} style={{ 40, height: 40}} />
    

    加载网络图片

    加载网络图片和加载资源图片一样,也要手动指定宽高度:

    <Image source={{uri: 'http://test.liuxianan.com/sample.jpg'}} style={{ 40, height: 40}} />
    

    组件的生命周期

    W740xH900

    附录:所有可用CSS列表

    注意:部分属性安卓不支持,如shadow

    RN中所有可用的CSS列表如下:

    "alignItems",
    "alignSelf",
    "backfaceVisibility",
    "backgroundColor",
    "borderBottomColor",
    "borderBottomLeftRadius",
    "borderBottomRightRadius",
    "borderBottomWidth",
    "borderColor",
    "borderLeftColor",
    "borderLeftWidth",
    "borderRadius",
    "borderRightColor",
    "borderRightWidth",
    "borderStyle",
    "borderTopColor",
    "borderTopLeftRadius",
    "borderTopRightRadius",
    "borderTopWidth",
    "borderWidth",
    "bottom",
    "color",
    "flex",
    "flexDirection",
    "flexWrap",
    "fontFamily",
    "fontSize",
    "fontStyle",
    "fontWeight",
    "height",
    "justifyContent",
    "left",
    "letterSpacing",
    "lineHeight",
    "margin",
    "marginBottom",
    "marginHorizontal",
    "marginLeft",
    "marginRight",
    "marginTop",
    "marginVertical",
    "opacity",
    "overflow",
    "padding",
    "paddingBottom",
    "paddingHorizontal",
    "paddingLeft",
    "paddingRight",
    "paddingTop",
    "paddingVertical",
    "position",
    "resizeMode",
    "right",
    "rotation",
    "scaleX",
    "scaleY",
    "shadowColor",
    "shadowOffset",
    "shadowOpacity",
    "shadowRadius",
    "textAlign",
    "textDecorationColor",
    "textDecorationLine",
    "textDecorationStyle",
    "tintColor",
    "top",
    "transform",
    "transformMatrix",
    "translateX",
    "translateY",
    "width",
    "writingDirection"

    参考

    http://blog.csdn.net/sbsujjbcy/article/details/50017029

  • 相关阅读:
    将数据保存在线程中
    OpenSmtp 的代码修正,支持中文和HTTP代理连接
    枚举.NET的基本类型
    通过HTTP代理连接到目的的协议
    程序出现了异常:应用程序无法启动,因为应用程序的并行配置不正确
    关于最近的一篇文章
    检测TextBox的回车键事件
    程序跳过trycatch地崩溃
    给程序加上UAC控制的几个链接
    Sql Server附加数据库的时候出现Operating system error 5: "5(Access is denied.)" 的错误
  • 原文地址:https://www.cnblogs.com/liuxianan/p/react-native-2.html
Copyright © 2011-2022 走看看