`
jsntghf
  • 浏览: 2532508 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

React Native之构建一个简单的列表页

    博客分类:
  • iOS
阅读更多

本文中我们将创建一个简单的电影应用,这个应用将从Rotten Tomatoes网站抓取目前正在上映的最新的25部电影,并将它们展示在一个ListView中。

 

一、伪造数据

 

在我们开始编写代码从Rotten Tomatoes网站抓取数据之前,我们先来伪造一些数据,以便我们可以马上体验一下React Native。我们一般会在JS文件的顶部声明常量,并在后面使用。在index.ios.js中添加以下代码:

var MOCKED_MOVIES_DATA = [
  {title: 'Title', year: '2015', posters: {thumbnail: 'http://i.imgur.com/UePbdph.jpg'}},
];

 

二、渲染一部电影

 

我们会渲染电影的标题、年份以及海报缩略图。由于缩略图在React Native中是一个Image组件,所以我们需要将Image组件加到React的依赖项中。

var {
  AppRegistry,
  Image,
  StyleSheet,
  Text,
  View,
} = React;

 

现在我们来修改render函数,以便我们可以渲染上面的模拟数据。

 

render: function() {
    var movie = MOCKED_MOVIES_DATA[0];
    return (
      <View style={styles.container}>
        <Text>{movie.title}</Text>
        <Text>{movie.year}</Text>
	    <Image
        	source={{uri: movie.posters.thumbnail}}
        	style={styles.thumbnail}
	 	/>
      </View>
    );
}

 

同时我们还需要修改styles,用来将样式应用到相应的组件上。

 

var styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  thumbnail: {
    width: 53,
    height: 81,
  },
});

 

按下cmd+R,此时的电影标题、年份以及海报缩略图已经渲染出来了。



 

三、修改样式,将文字放在图片的右侧

 

接下来,我们把文字放在图片的右侧,同时让标题字体大一些并居中显示。

 

修改render函数,添加另一个View,这是为了让我们的组件在最外层的组件中垂直居中显示。

 

render: function() {
    var movie = MOCKED_MOVIES_DATA[0];
    return (
      <View style={styles.container}>
        <Image
    	    source={{uri: movie.posters.thumbnail}}
    	    style={styles.thumbnail}
 	    />
		<View style={styles.rightContainer}>
        	<Text style={styles.title}>{movie.title}</Text>
        	<Text style={styles.year}>{movie.year}</Text>
        </View>
      </View>
    );
}

 

同时我们还需要修改styles,用来将样式应用到相应的组件上。

 

var styles = StyleSheet.create({
  container: {
    flex: 1,
	flexDirection: 'row',
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  thumbnail: {
    width: 53,
    height: 81,
  },
  rightContainer: {
    flex: 1,
  },
  title: {
    fontSize: 20,
    marginBottom: 8,
    textAlign: 'center',
  },
  year: {
    textAlign: 'center',
  },
});

 

按下cmd+R来查看更新之后的视图。



 

四、抓取真实数据

 

将下面的常量放在文件的顶部,用来创建一个请求数据使用的REQUEST_URL:

 

var API_KEY = '7waqfqbprs7pajbz28mqf6vz';
var API_URL = 'http://api.rottentomatoes.com/api/public/v1.0/lists/movies/in_theaters.json';
var PAGE_SIZE = 25;
var PARAMS = '?apikey=' + API_KEY + '&page_limit=' + PAGE_SIZE;
var REQUEST_URL = API_URL + PARAMS;

 

为我们的应用添加初始状态,这样我们可以通过检查this.state.movies === null来确定电影数据有没有被加载。当电影数据返回时,我们可以通过this.setState({movies: moviesData})来设置数据。

 

将下面的代码添加到render函数之前:

 

getInitialState: function() {
    return {
      movies: null,
    };
},

 

我们想要在组件完成加载后发送请求,componentDidMount是React组件中的一个函数,它只会在组件加载完成后被调用一次。

 

componentDidMount: function() {
    this.fetchData();
},

 

接下来添加组件中会用到的fetchData函数,这个函数将负责处理数据的抓取。你需要做的仅仅是在promise完成解析后调用this.setState({movies: data})。因为setState会触发重新渲染,而此时render函数会注意到this.state.movies不再是null。

 

注意一定要在promise链的最后调用done(),否则错误信息可能会被忽略。

 

fetchData: function() {
    fetch(REQUEST_URL)
      .then((response) => response.json())
      .then((responseData) => {
        this.setState({
          movies: responseData.movies,
        });
      })
      .done();
},

 

现在修改render函数,如果电影数据还没有返回的话,就渲染一个loading视图,否则将渲染第一部电影。

 

render: function() {
    if (!this.state.movies) {
      return this.renderLoadingView();
    }

    var movie = this.state.movies[0];
    return this.renderMovie(movie);
},

renderLoadingView: function() {
    return (
      <View style={styles.container}>
        <Text>
          Loading movies...
        </Text>
      </View>
    );
},

renderMovie: function(movie) {
    return (
      <View style={styles.container}>
        <Image
          source={{uri: movie.posters.thumbnail}}
          style={styles.thumbnail}
        />
        <View style={styles.rightContainer}>
          <Text style={styles.title}>{movie.title}</Text>
          <Text style={styles.year}>{movie.year}</Text>
        </View>
      </View>
    );
},

 

按下cmd+R,首先会看到loading页面




电影数据返回后,就会渲染第一部从Rotten Tomatoes获取过来的电影。



 

五、显示完整的电影列表

 

现在我们来修改应用,将所有的数据渲染在一个ListView组件中,而不是只渲染一部电影。

 

这里使用ListView是因为ListView会自动渲染视线之内的视图,而那些在屏幕之外的视图会被暂时移除。

 

这里既然用到了ListView,我们就需要将ListView组件加到React的依赖项中。

 

var {
  AppRegistry,
  Image,
  ListView,
  StyleSheet,
  Text,
  View,
} = React;

 

接下来修改render函数,一旦数据返回就可以在ListView里面渲染数据:

 

render: function() {
	if (!this.state.loaded) {
	      return this.renderLoadingView();
	}

	return (
	  <ListView
	    dataSource={this.state.dataSource}
	    renderRow={this.renderMovie}
	    style={styles.listView}
	  />
	);
},

 

DataSource是ListView的一个接口,作用是决定哪些行会改变。

 

接下来,我们需要在getInitialState的返回对象上添加一个空的dataSource,我们不能再使用this.state.movies防止数据被存储两次。我们可以使用this.state.loaded来判断数据抓取是否结束。

 

getInitialState: function() {
    return {
      dataSource: new ListView.DataSource({
        rowHasChanged: (row1, row2) => row1 !== row2,
      }),
      loaded: false,
    };
},

 

我们还需要修改fetchData来更新state:

 

fetchData: function() {
    fetch(REQUEST_URL)
      .then((response) => response.json())
      .then((responseData) => {
        this.setState({
          dataSource: this.state.dataSource.cloneWithRows(responseData.movies),
          loaded: true,
        });
      })
      .done();
},

 

最后,我们在styles中为ListView组件添加样式: 

 

listView: {
    paddingTop: 20,
    backgroundColor: '#F5FCFF',
},

 

下面是最终的效果图:



 

六、本文最终完整的源码

 

'use strict';

var React = require('react-native');

var API_KEY = '7waqfqbprs7pajbz28mqf6vz';
var API_URL = 'http://api.rottentomatoes.com/api/public/v1.0/lists/movies/in_theaters.json';
var PAGE_SIZE = 25;
var PARAMS = '?apikey=' + API_KEY + '&page_limit=' + PAGE_SIZE;
var REQUEST_URL = API_URL + PARAMS;

var {
  AppRegistry,
  Image,
  ListView,
  StyleSheet,
  Text,
  View,
} = React;

var Movie = React.createClass({
	getInitialState: function() {
	    return {
	      dataSource: new ListView.DataSource({
	        rowHasChanged: (row1, row2) => row1 !== row2,
	      }),
	      loaded: false,
	    };
	},
	componentDidMount: function() {
	    this.fetchData();
	},
	fetchData: function() {
	    fetch(REQUEST_URL)
	      .then((response) => response.json())
	      .then((responseData) => {
	        this.setState({
	          dataSource: this.state.dataSource.cloneWithRows(responseData.movies),
	          loaded: true,
	        });
	      })
	      .done();
	},
	render: function() {
		if (!this.state.loaded) {
		      return this.renderLoadingView();
		}

		return (
		  <ListView
		    dataSource={this.state.dataSource}
		    renderRow={this.renderMovie}
		    style={styles.listView}
		  />
		);
	},

	renderLoadingView: function() {
	    return (
	      <View style={styles.container}>
	        <Text>
	          Loading movies...
	        </Text>
	      </View>
	    );
	},

	renderMovie: function(movie) {
	    return (
	      <View style={styles.container}>
	        <Image
	          source={{uri: movie.posters.thumbnail}}
	          style={styles.thumbnail}
	        />
	        <View style={styles.rightContainer}>
	          <Text style={styles.title}>{movie.title}</Text>
	          <Text style={styles.year}>{movie.year}</Text>
	        </View>
	      </View>
	    );
	},
});

var styles = StyleSheet.create({
  container: {
    flex: 1,
	flexDirection: 'row',
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  thumbnail: {
    width: 53,
    height: 81,
  },
  rightContainer: {
    flex: 1,
  },
  title: {
    fontSize: 20,
    marginBottom: 8,
    textAlign: 'center',
  },
  year: {
    textAlign: 'center',
  },
  listView: {
      paddingTop: 20,
      backgroundColor: '#F5FCFF',
  },
});

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

 

分享到:
评论

相关推荐

    reactnativepage一个简单的reactnative分页组件

    总结来说,React Native Page 是一个适用于React Native开发的分页组件,它简化了在移动应用中实现分页功能的过程,让开发者能够更加专注于业务逻辑和用户体验。通过熟练掌握和运用这个组件,可以提高开发效率,为...

    React Native 瀑布流列表

    1. **React Native基础知识**:React Native是Facebook推出的一个开源框架,它允许开发者使用JavaScript和React来开发原生移动应用。React是Facebook的UI库,采用组件化思想,而React Native则是将其扩展到移动平台...

    用reactnative开发的一个简单跑马灯抽奖demo

    在这个“用React Native开发的一个简单跑马灯抽奖demo”项目中,我们看到了React Native在创建动态、交互式用户界面方面的应用。 首先,让我们深入了解一下React Navigation。React Navigation是一个流行的导航解决...

    React Native Debugger reactnative可视化调试工具

    React Native Debugger是一款强大的开发工具,特别为在macOS平台上进行React和React Native应用的可视化调试而设计。它提供了丰富的功能,使开发者能够更有效地检查、调试和优化代码,尤其是在处理复杂的Redux状态...

    采用ReactNative和Exponent构建的可展开列表集合组件

    在本文中,我们将深入探讨如何使用React Native和Exponent来构建一个可展开的列表集合组件。React Native是一种流行的JavaScript框架,用于开发原生移动应用程序,而Exponent则是一个平台,可以简化React Native应用...

    一个强大的ReactNative滑动组件

    React Native滑动组件(react-native-swipeable)是基于此框架的一个扩展库,它提供了一种简单的方式来实现滑动相关的交互,如卡片滑动删除、列表项的左右滑动等常见操作。 滑动组件的核心功能包括: 1. **双向...

    reactnative实现的折叠列表二级列表展开点击时改变字体颜色

    在React Native中构建一个具有折叠效果的二级列表,并在点击时改变字体颜色,涉及到的关键技术主要包括React Native的基础组件使用、ListView的实现以及事件处理。React Native是Facebook推出的一个开源框架,它允许...

    React-Native 实现点击Tab标签切换Tab页面

    React-Native是由Facebook开发的一个开源框架,它允许开发者使用JavaScript和React来构建原生移动应用。React是Facebook推出的用于构建用户界面的JavaScript库,它的核心理念是组件化,通过组合多个小而独立的组件来...

    快速搭建ReactNative项目的一个starter

    React Native 是一个由...总的来说,“快速搭建React Native项目的一个starter”是一个宝贵的资源,可以帮助开发者高效地开始他们的React Native之旅,利用已有的配置和最佳实践,快速构建出功能丰富的移动应用。

    30天学习ReactNative教程

    使用`react-native init`命令初始化一个新的React Native项目,这会为你生成项目模板。了解项目目录结构,包括`src`目录中的`App.js`,这是应用的入口点。 4. **组件化编程** 学习如何定义和使用组件,如状态...

    ReactNative项目demo

    ReactNative项目Demo是一个基于ReactNative框架构建的针对iPad设备的应用示例。ReactNative是由Facebook开发的开源库,它允许开发者使用JavaScript和React编程理念来构建原生移动应用程序。这个项目Demo旨在提供一个...

    一个基于reactnative开发的完整项目示例

    这个“RNExampleApp-master”压缩包文件很可能包含了一个完整的React Native项目实例,让我们来深入探讨一下相关的关键知识点。 1. **React Native基础**:React Native的核心理念是“Learn once, write anywhere”...

    为你的reactnative应用程序实现一个气泡菜单效果

    本教程将指导你如何为你的React Native应用添加一个气泡菜单效果。 首先,你需要了解React Native的基本概念。React Native是由Facebook开发的开源框架,它允许使用JavaScript和React来构建原生移动应用。通过JSX...

    Android项目中集成react native页面

    1. **React Native简介**:React Native是Facebook开源的一个框架,它允许开发者使用JavaScript和React组件库来构建原生的iOS和Android应用程序。它的核心理念是“Learn once, write anywhere”,即学习一次,到处...

    reactnative混编构建的app

    React Native 混编构建的App是现代移动应用开发中的一个重要技术实践,它结合了JavaScript的灵活性和原生平台的强大性能。React Native是由Facebook开发的一个开源框架,允许开发者使用JavaScript和React库来创建高...

    ReactNative组件用于创建圆形进度滑块

    React Native 是一个流行的开源框架,它允许开发者使用JavaScript来构建原生的移动应用程序。这个框架的优势在于其跨平台的能力,可以同时为iOS和Android提供一致的用户体验。在React Native中,组件是构建用户界面...

    react native uwp app

    2. **创建项目**:使用`react-native init`命令创建一个新的React Native项目,然后根据UWP要求进行调整。 3. **集成UWP**:将项目配置为支持UWP平台,添加必要的依赖,并解决可能出现的平台特定问题。 4. **开发和...

    使用reactnative开发的一个one客户端

    在“使用react native开发的一个one客户端”这个项目中,我们可以理解为开发者已经利用React Native技术创建了一个名为“ONE”的移动应用客户端。这个客户端可能是针对某种特定服务或平台,如在线阅读、学习资源、...

    一个ReactNative自定义键盘插件

    React Native 是一个由Facebook开发的开源框架,它允许开发者使用JavaScript和React的组件化思想来构建原生的iOS和Android应用程序。在这个特定的场景中,我们讨论的是一个React Native的自定义键盘插件,这对于创建...

Global site tag (gtag.js) - Google Analytics