ReactNative豆瓣电影项目
欢迎访问我的博客https://qqqww.com/,祝码农同胞们早日走上人生巅峰,迎娶白富美~~~
文章目录
- 1 ReactNative项目环境搭建
- 2 首页
- 2.1 如何更改首页
- 3 组件的学习
- 4 正式开始豆瓣电影项目
- 4.1 Tabbar
- 4.1.1 基本结构
- 4.1.2 组件高亮和切换
- 4.1.3 组件的图标
- 4.1.3.1 **安装**
- 4.1.3.2 配置
- 4.1.3.3 重新打包构建
- 4.1.3.4 导入
- 4.1.3.5 使用
- 4.2 主页
- 4.2.1 主页轮播图
- 4.2.1.1 静态页面
- 4.2.2.2 渲染数据
- 4.2.3 主页六宫格
- 4.3 热映电影
- 4.3.1 Main.js 配置路由
- 4.3.2 豆瓣热映电影列表
- 4.3.2.1 基本页面
- 4.3.2.2 豆瓣接口
- 4.3.2.3 fetch获取电影列表数据
- 4.3.2.4 渲染电影列表数据
- 4.3.2.5 美化布局
- 4.3.2.6 下拉加载更多
- 4.3.2.7 提升体验
- 4.3.3 豆瓣热映电影详情
- 4.3.3.1 基本页面
- 4.3.3.2 数据渲染
- 5 小功能体验:拍照功能
- 6 发布安卓项目
- 7 参考文章
项目技能:react,react-native,android环境
项目目的:只做项目环境搭建和小部分功能以练习react-native基本功能和android上app的打包构建
项目地址:ReactNative豆瓣电影
1 ReactNative项目环境搭建
请参考我这个文档ReactNative项目环境搭建
2 首页
在进行这一步之前,先确认项目环境搭建并打包下载到手机上没有任何问题之后,进行之后的代码编写和调试
2.1 如何更改首页
知识点:
View组件
和Text组件
编写一个自己的首页:根目录下创建MyHomePage.js
作为自己的首页
注意:在 RN 中只能使用 .js 不能使用 .jsx
/*** 自己的首页*/// 导入 react
import React, { Component } from 'react'
// 按需导入组件, View 组件就好比网页中的 div 元素
import { View, Text } from 'react-native'export default class MyHomePage extends Component {constructor(props) {super(props)this.state = {}}render() {// 1. 在 RN 中不能使用在网页中的所有标签// 2. 如果想要实现布局,RN 提供了一个叫做 View 的组件,来实现布局, 想要使用,要先导入return (<View> { /*3. 在 RN 中,所有的文本,必须使用 RN 提供的 Text 组件进行包裹,依然是按需导入*/ }<Text>123456</Text></View>)}
}
在
index.js
中导入自己的组件
// 导入自己的组件页面
import MyHomePage from './MyHomePage.js'
// 当使用 AppRegistry 注册项目的时候,方法中的第一个参数不要改
// 第二个参数表示要把哪个页面注册为首页
AppRegistry.registerComponent(appName, () => MyHomePage);
3 组件的学习
ReactNative组件
4 正式开始豆瓣电影项目
练习了上面一些组件和属性之后,着手去做一个豆瓣电影的小项目
4.1 Tabbar
4.1.1 基本结构
使用组件
react-native-tab-navigator
react-native-tab-navigator使用方法:老套路,对照官方文档,装包=>导入=>使用
这里的装包,不推荐使用
npm
,首先下载慢,其次如果是npm5.X
在装新包的时候会把一些老包删除,可能会出现猝不及防的惊喜~~~~
我这里使用的是
yarn
装包
yarn add react-native-tab-navigator // 默认是 --save
// 导入 Tabbvar 相关组件
import TabNavigator from 'react-native-tab-navigator'
export default class MyHomePage extends Component {constructor(props) {super(props)this.state = {}}render() {// 1. 在 RN 中不能使用在网页中的所有标签// 2. 如果想要实现布局,RN 提供了一个叫做 View 的组件,来实现布局, 想要使用,要先导入return (<View style={styles.container}> <TabNavigator><TabNavigator.Item title="Home">// 放入组件</TabNavigator.Item><TabNavigator.Item title="Me">// 放入组件</TabNavigator.Item> </TabNavigator></View>);}
}
const styles = StyleSheet.create({container: {flex: 1}
});
这里的放入组件的位置是自己创建的组件,其他后面的自己创建的组件引入方式也是一样套路
创建自己的组件
=>引入
=>使用
创建自己的新组件,
components/tabars/Home.js
和components/tabars/Me.js
两个组件都简单写下基本代码
import React, { Component } from 'react'
import { View, Text } from 'react-native'export default class Search extends Component {render() {return <View><Text>这是 Home 组件</Text></View>}
}
引入
import Home from './components/tabbars/Home.js'
import Me from './components/tabbars/Me.js'
使用
<View style={styles.container}> <TabNavigator><TabNavigator.Item title="Home"><Home></Home></TabNavigator.Item><TabNavigator.Item title="Me"><Me></Me></TabNavigator.Item> </TabNavigator>
</View>);
4.1.2 组件高亮和切换
拿
home
组件举例子,官方文档上这两句加上就行了
selected={this.state.selectedTab === 'home'}
onPress={() => this.setState({ selectedTab: 'home' })}>
Tab栏的四个组件都按照这样写完,就可以实现正常切换了
4.1.3 组件的图标
用
react-native-vector-icons
的组件,安装
=>配置
=>导入
=>使用
4.1.3.1 安装
yarn add react-native-vector-icons
4.1.3.2 配置
- 在官方文档找到对应的手机平台配置,我这里应为开发的是
Android
,所以配置的是Android
的- 编辑
android/app/build.gradle( NOT android/build.gradle )
,去这个文件中添加下面两行代码
project.ext.vectoricons = [iconFontNames: [ 'MaterialIcons.ttf', 'EvilIcons.ttf', 'FontAwesome.ttf' ] // Name of the font files you want to copy
]apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"
- fonts文件找到自己的字体文件
C:\Users\wanggongtou\Desktop\douban\node_modules\react-native-vector-icons\Fonts
下面的所有文件全部复制放到android/app/src/main/assets/fonts
,下面没有assets/fonts
就手动创建一个,再复制进来- 将下面两行代码放到
android/settings.gradle
下合适的位置,并把前面的+
去掉
+ include ':react-native-vector-icons'
+ project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android')
编辑
android/app/build.gradle
,找到dependencies
的大括号内部加上compile project(':react-native-vector-icons')
dependencies {...compile project(':react-native-vector-icons')
}
编辑
android\app\src\main\java\com\douban\MainApplication.java
在package com.douban;
这句代码下面添加
import com.oblador.vectoricons.VectorIconsPackage;
这句代码,在同一个文件中,找到protected List<ReactPackage> getPackages()
在其内部,加上, new VectorIconsPackage()
package com.douban;
import com.oblador.vectoricons.VectorIconsPackage;@Overrideprotected List<ReactPackage> getPackages() {return Arrays.<ReactPackage>asList(new MainReactPackage(), new VectorIconsPackage());}
注意:只要修改了
Android
里面的配置文件,要重新打包构建
4.1.3.3 重新打包构建
react-native run-android
这里可能会遇到两点问题:
问题一:提示没有licenses
协议
解决方案:去配置Android
的环境目录下,找到 Android SDK Manager
安装 Android SDK Build-tools 23.0.1
并接受其 license
;
注意:这里的 Android SDK Build-tools 23.0.1
版本号需要和自己的构建工具版本号相对应
问题二:打包构建之后,发现手机上的app打开没有页面了
解决方案:关闭APP进程,重新打开一下就有了
4.1.3.4 导入
import Icon from 'react-native-vector-icons/FontAwesome'
4.1.3.5 使用
可以去
FontAwesome
官网列表中查找对应组件需要的图标,Icon name=图标的名字
就可以了
<TabNavigator><TabNavigator.Item...renderIcon={() => <Icon name="home" size={25} color="gray" />} // 未选中状态下,展示的图标renderSelectedIcon={() => <Icon name="home" size={25} color="#0079FF" />} // 选中状态下展示的图标...<Home></Home></TabNavigator.Item></TabNavigator>
4.2 主页
4.2.1 主页轮播图
4.2.1.1 静态页面
找组件
react-native-swiper
去官网看, 安装、导入、使用
yarn add react-native-swiper
因为轮播图在主页,所以在主页的组件中进行导入
// 导入轮播图组件
import Swiper from 'react-native-swiper'
把对应的结构和样式全部都拷贝过来
export default class Search extends Component {render() {return (<Swiper style={styles.wrapper} showsButtons={true}><View style={styles.slide1}><Text style={styles.text}>Hello Swiper</Text></View><View style={styles.slide2}><Text style={styles.text}>Beautiful</Text></View><View style={styles.slide3}><Text style={styles.text}>And simple</Text></View></Swiper>);}
}const styles = StyleSheet.create({wrapper: {},slide1: {flex: 1,justifyContent: 'center',alignItems: 'center',backgroundColor: '#9DD6EB',},slide2: {flex: 1,justifyContent: 'center',alignItems: 'center',backgroundColor: '#97CAE5',},slide3: {flex: 1,justifyContent: 'center',alignItems: 'center',backgroundColor: '#92BBD9',},text: {color: '#fff',fontSize: 30,fontWeight: 'bold',}
})
这里轮播图就出来了,再设置自动轮播和轮播图高度,由于这里的轮播图默认充满全屏,所以可以给轮播图最外层套一个
View
,给它一个高度
<View style={{ height: 220 }}>// 放轮播图代码
</View>
给
Swiper
盒子加上属性,自动轮播
<Swiper style={styles.wrapper} showsButtons={true} autoplay={true} loop={true}>...
</Swiper>
4.2.2.2 渲染数据
export default class Home extends Component {constructor(props) {super(props)this.state = {banner: [] // 轮播图数组}}componentWillMount() {fetch('http://www.liulongbin.top:3005/api/getlunbo').then(res => res.json()).then(data => {// console.warn(JSON.stringify(data, null, ' '))this.setState({banner: data.message})})}render() {return (<View style={{ height: 220 }}><Swiper style={styles.wrapper} showsButtons={true} autoplay={true} loop={true}>{this.state.banner.map((item, i) => {return <View key={i}><Image source={{uri: item.img}} style={{width: '100%', height: '100%'}}></Image></View>})}</Swiper></View>); }
}
4.2.3 主页六宫格
导入所需要的组件
import { AppRegistry, StyleSheet, View, Text, Image, TouchableHighlight } from 'react-native'
// 六宫格区域
{/* 在 RN 中,默认,就已经为 所有的 View 启用了弹性和模型,同时,默认的主轴是 纵向的 */}<View style={{ flexDirection: 'row', flexWrap: 'wrap' }}><View style={styles.box}><Image source={require('../../images/menu1.png')} style={{ width: 60, height: 60 }}></Image><Text>新闻资讯</Text></View>// ...这里根据需求可以增加主页的宫格数目,我这里是六个,上面代码复制六份就可以</View>
var styles = StyleSheet.create({box: {width: '33.33%',alignItems: 'center',marginTop: 15}
})
4.3 热映电影
4.3.1 Main.js 配置路由
在项目根目录新建一个
Main.js
作为项目根组件,修改一下index.js
中指向App.js
的代码
import Main from './Main.js'
AppRegistry.registerComponent(appName, () => Main);
去编辑
Main.js
的代码
// Main 项目的根组件
// 导入组件
import React, { Component } from 'react'
import { View, Image, Text, ActivityIndicator } from 'react-native'
安装一个配置路由规则的插件
react-native-router-flux
yarn add react-native-router-flux
在
Main.js
中导入
import { Router, Stack, Scene } from 'react-native-router-flux'
Router: 就相当于 HashRouter
Stack: 这是一个分组的容器,他不表示具体的路由,专门用来给路由分组的
Scene:就表示一个具体的路由规则,好比 昨天学到的 Route
新建两个组件
components/movie/MovieList.js
和components/movie/MovieDetail.js
作为电影列表组件和电影描述组件
而且由于更换了项目的根组件,所以需要在
Main.js
中导入App.js
// 导入组件
import App from './App.js'
import MovieList from './components/movie/MovieList.js'
import MovieDetail from './components/movie/MovieDetail.js'
继续修改代码将
App.js
作为首页展示,在render
渲染的时候,可以配置首页,并且一并配置其他页面路由
render() {return <Router sceneStyle={{ backgroundColor: 'white' }}><Stack key="root">{/* 配置路由规则 */}{/* 注意,所有的路由规则,都应该写到这个位置 */}{/* 第一个 Scene 就是默认要展示的首页 */}{/* key 属性,表示路由的规则名称,将来可以使用这个 key ,进行编程式导航,每一个路由规则,都应该提供一个 唯一的key, key不能重复 */}<Scene key="app" component={App} title="" hideNavBar={true} />{/* 电影列表的路由规则 */}<Scene key="movielist" component={MovieList} title="热映电影列表" /><Scene key="moviedetail" component={MovieDetail} title="电影详情" /></Stack></Router>}
这个时候,依然是不能点击跳转的,是因为没有给
Home.js
内部的热映电影
组件绑定点击事件,所以去帮顶下
用
TouchableHighlight
包裹Home.js
中的热映电影
的代码片段
// 在使用前应该现在最前面导入该组件
import { AppRegistry, StyleSheet, View, Text, Image, TouchableHighlight } from 'react-native'// 包裹<TouchableHighlight onPress={this.goMovieList} underlayColor="white" style={styles.box}>{/* 在 TouchableHighlight 内部,只能放置唯一的一个元素 */}<View><Image source={require('../../images/menu5.png')} style={{ width: 60, height: 60 }}></Image><Text>热映电影</Text></View></TouchableHighlight>
// goMovieList 方法在下面定义
导入
Actions
组件,实现编程式导航
// 导入 Actions 组件,实现编程式导航
// Actions 表示要进行 JS 操作了
import { Actions } from 'react-native-router-flux'
写一个跳转方法,并去
TouchableHighlight
中绑定这个方法
render() {...goMovieList = () => {Actions.movielist()}
}
<TouchableHighlight onPress={this.goMovieList} underlayColor="white" style={styles.box}>
这样就实现了基本的路由跳转
4.3.2 豆瓣热映电影列表
4.3.2.1 基本页面
import React, { Component } from 'react'
import { View, Image, Text, StyleSheet, ... } from 'react-native'const styles = StyleSheet.create({...
})// 导入路由的组件
import { Actions } from 'react-native-router-flux'export default class MovieList extends Component {constructor(props) {super(props)this.state = {...}}componentWillMount() {...}render() {return ...}...
}
4.3.2.2 豆瓣接口
这里先说一下豆瓣接口,根据接口可以进行数据的获取
访问https://api.douban.com/v2/movie/in_theaters?start=0&count=12可以看到豆瓣的电影数据,链接中的
?
后面的参数start
表示开始页码,count
表示每页显示的记录条数,可以根据需求修改,可以拷贝假数据用于测试,可以调用接口,用于测试方法成功之后进行动态数据的渲染
4.3.2.3 fetch获取电影列表数据
- 根据页码获取电影列表数据
- 渲染电影列表的方法测试
- 每项数据需要同步
this.state
中
export default class MovieList extends Component {constructor(props) {super(props)this.state = {movies: [], // 电影列表nowPage: 1, // 当前的页码totalPage: 0, // 总页数pageSize: 15, // 每页显示的记录条数isloading: true // 是否正在加载数据}}componentWillMount() {this.getMoviesByPage()}render() {return <View>{this.renderList()}</View>}// 根据页码获取电影列表getMoviesByPage = () => {const start = (this.state.nowPage - 1) * this.state.pageSizeconst url = `https://api.douban.com/v2/movie/in_theaters?start=${start}&count=${this.state.pageSize}`/*fetch(url).then(res => res.json()).then(data => {this.setState({isloading: false,movies: this.state.movies.concat(data.subjects),totalPage: Math.ceil(data.total / this.state.pageSize)})})*//* 此代码用了拷贝的假数据用于测试 */setTimeout(() => {this.setState({isloading: false,movies: require('./test_list.json').subjects,totalPage: 1})}, 1000) }// 渲染电影列表的方法,此处用于测试,若能获取电影条数则方法可以继续往下写renderList = () => {if (this.state.isloading) {return <ActivityIndicator size="large"></ActivityIndicator>}return <View><Text>{this.state.moives.length}</Text></View>}...
}
4.3.2.4 渲染电影列表数据
// 渲染电影列表的方法renderList = () => {if (this.state.isloading) {return <ActivityIndicator size="large"></ActivityIndicator>}return <FlatListdata={this.state.movies}keyExtractor={(item, i) => i} // 解决 key 问题renderItem={({ item }) => this.renderItem(item)} // 调用方法,去渲染每一项/>}// 渲染每项电影renderItem = (item) => {return <TouchableHighlight><View><Image source={{ uri: item.images.small }} style={{ width: 100, height: 140, marginRight: 10 }}></Image><View><Text><Text style={styles.movieTitle}>电影名称:</Text>{item.title}</Text><Text><Text style={styles.movieTitle}>电影类型:</Text>{item.genres.join(',')}</Text><Text><Text style={styles.movieTitle}>制作年份:</Text>{item.year}年</Text><Text><Text style={styles.movieTitle}>豆瓣评分:</Text>{item.rating.average}分</Text></View></View></TouchableHighlight>}
4.3.2.5 美化布局
相当于加一些样式,不然太丑了
// 渲染电影列表的方法renderList = () => {if (this.state.isloading) {return <ActivityIndicator size="large"></ActivityIndicator>}return <FlatListdata={this.state.movies}keyExtractor={(item, i) => i} // 解决 key 问题renderItem={({ item }) => this.renderItem(item)} // 调用方法,去渲染每一项ItemSeparatorComponent={this.renderSeparator} //渲染分割线的属性方法onEndReachedThreshold={0.5} // 距离底部还有多远的时候,触发加载更多的事件onEndReached={this.loadNextPage} // 当距离不足 0.5 的时候,触发这个方法,加载下一页数据/>}// 渲染每项电影renderItem = (item) => {return <View style={{ flexDirection: 'row', padding: 10 }}><Image source={{ uri: item.images.small }} style={{ width: 100, height: 140, marginRight: 10 }}></Image><View style={{ justifyContent: 'space-around' }}><Text><Text style={styles.movieTitle}>电影名称:</Text>{item.title}</Text><Text><Text style={styles.movieTitle}>电影类型:</Text>{item.genres.join(',')}</Text><Text><Text style={styles.movieTitle}>制作年份:</Text>{item.year}年</Text><Text><Text style={styles.movieTitle}>豆瓣评分:</Text>{item.rating.average}分</Text></View></View>}// 渲染分割线renderSeparator = () => {return <View style={{ borderTopColor: '#ccc', borderTopWidth: 1, marginLeft: 10, marginRight: 10 }}></View>}
4.3.2.6 下拉加载更多
利用官方文档的属性
onEndReachedThreshold
和onEndReached
来控制
onEndReachedThreshold
距离底部还有多远的时候,触发加载更多的事件
onEndReached:
当距离不足 0.5 的时候,触发这个方法,加载下一页数据
// 渲染电影列表的方法renderList = () => {if (this.state.isloading) {return <ActivityIndicator size="large"></ActivityIndicator>}return <FlatListdata={this.state.movies}keyExtractor={(item, i) => i} // 解决 key 问题renderItem={({ item }) => this.renderItem(item)} // 调用方法,去渲染每一项ItemSeparatorComponent={this.renderSeparator} //渲染分割线的属性方法onEndReachedThreshold={0.5} // 距离底部还有多远的时候,触发加载更多的事件onEndReached={this.loadNextPage} // 当距离不足 0.5 的时候,触发这个方法,加载下一页数据/>}// 渲染每项电影renderItem = (item) => {return <TouchableHighlight underlayColor="#fff" onPress={() => { Actions.moviedetail({ id: item.id }) }}><View style={{ flexDirection: 'row', padding: 10 }}><Image source={{ uri: item.images.small }} style={{ width: 100, height: 140, marginRight: 10 }}></Image><View style={{ justifyContent: 'space-around' }}><Text><Text style={styles.movieTitle}>电影名称:</Text>{item.title}</Text><Text><Text style={styles.movieTitle}>电影类型:</Text>{item.genres.join(',')}</Text><Text><Text style={styles.movieTitle}>制作年份:</Text>{item.year}年</Text><Text><Text style={styles.movieTitle}>豆瓣评分:</Text>{item.rating.average}分</Text></View></View></TouchableHighlight>}// 加载下一页loadNextPage = () => {// 如果下一页的页码值,大于总页数了,直接returnif ((this.state.nowPage + 1) > this.state.totalPage) {return}this.setState({nowPage: this.state.nowPage + 1}, function () {this.getMoviesByPage()})}
4.3.2.7 提升体验
写着写着,遇到了个问题,这时不时的访问不到服务,但是这好像和代码关系不大,因为我重连几次就可以了,我觉得和网速关系很大,我这网速太渣
所以我就加了几句提示错误的代码
getMoviesByPage = () => {const start = (this.state.nowPage - 1) * this.state.pageSizeconst url = `https://api.douban.com/v2/movie/in_theaters?start=${start}&count=${this.state.pageSize}`fetch(url).then(res => {if (res.ok) {return res.json()} else {console.error('服务器忙,请稍后重试' + res.status)}}).then(data => {...}).catch(err => {console.error(err)})}
4.3.3 豆瓣热映电影详情
4.3.3.1 基本页面
import React, { Component } from 'react'import { View, Image, Text, ActivityIndicator, ScrollView } from 'react-native'export default class MovieDetail extends Component {constructor(props) {super(props)this.state = {movieInfo: {}, // 电影信息isloading: true}}componentWillMount() {...}render() {return <View>...</View>}...
}
同样的需要去
Main.js
配置路由规则,和配置MovieList
组件的路由规则一个套路,这里由于我之前配置过了,不再配置
给
MovieDetil
在MovieList
中的代码片段(就是渲染的每一部电影的代码片段)加上链接跳转,这里依然是要依靠TouchableHighlight
组件
首先引入
import { View, Image, Text, ActivityIndicator, FlatList, StyleSheet, TouchableHighlight } from 'react-native'
在获取每项电影的时候,代码片段用TouchableHighlight
包裹起来
renderItem = (item) => {return <TouchableHighlight underlayColor="#fff"><View style={{ flexDirection: 'row', padding: 10 }}><Image source={{ uri: item.images.small }} style={{ width: 100, height: 140, marginRight: 10 }}></Image><View style={{ justifyContent: 'space-around' }}><Text><Text style={styles.movieTitle}>电影名称:</Text>{item.title}</Text><Text><Text style={styles.movieTitle}>电影类型:</Text>{item.genres.join(',')}</Text><Text><Text style={styles.movieTitle}>制作年份:</Text>{item.year}年</Text><Text><Text style={styles.movieTitle}>豆瓣评分:</Text>{item.rating.average}分</Text></View></View></TouchableHighlight>}
绑定点击事件,并导入
Actions
,实现编程式导航
// 导入路由的组件
import { Actions } from 'react-native-router-flux'
// 渲染每项电影renderItem = (item) => {return <TouchableHighlight underlayColor="#fff" onPress={() => { Actions.moviedetail({ id: item.id }) }}>...</TouchableHighlight>}
4.3.3.2 数据渲染
在生命周期是
componentWillMount()
的时候从接口获取数据,再到this.state
同步数据,然后去render()
填充数据,这里为render()
定义了一个方法,直接this.renderInfo()
调用就可以
import React, { Component } from 'react'import { View, Image, Text, ActivityIndicator, ScrollView } from 'react-native'export default class MovieDetail extends Component {constructor(props) {super(props)this.state = {movieInfo: {}, // 电影信息isloading: true}}componentWillMount() {fetch('https://api.douban.com/v2/movie/subject/' + this.props.id).then(res => res.json()).then(data => {this.setState({movieInfo: data,isloading: false})})}render() {return <View>{this.renderInfo()}</View>}renderInfo = () => {if (this.state.isloading) {return <ActivityIndicator size="large"></ActivityIndicator>}return <ScrollView><View style={{ padding: 4 }}><Text style={{ fontSize: 25, textAlign: 'center', marginTop: 20, marginBottom: 20 }}>{this.state.movieInfo.title}</Text><View style={{ alignItems: 'center' }}><Image source={{ uri: this.state.movieInfo.images.large }} style={{ width: 200, height: 280 }}></Image></View><Text style={{ lineHeight: 30, marginTop: 20 }}>{this.state.movieInfo.summary}</Text></View></ScrollView>}
}
提示:各种接口数据最好借助
Postman
工具,先看一下接口数据里哪些属性要用,不然挺乱的,不过不借助Psotman
工具的话也可以去该接口连接把json
数据拷贝下来到编辑器中,自己整理下格式
5 小功能体验:拍照功能
为
Me.js
添加一个拍照功能
调用插件
react-native-image-picker
该插件可以调用摄像头
- 安装包
yarn add react-native-image-picker
- 导入包
import { View, Button, Image } from 'react-native'
// 导入拍照的包
import ImagePicker from 'react-native-image-picker'
- 创建拍照时的配置对象
var photoOptions = {//底部弹出框选项title: '请选择',cancelButtonTitle: '取消',takePhotoButtonTitle: '拍照',chooseFromLibraryButtonTitle: '选择相册',quality: 0.75, // 照片的质量allowsEditing: true, // 允许被编辑noData: false, // 拍照时候不附带日期storageOptions: { // 存储选项skipBackup: true, // 在IOS平台中,会自动把 照片同步到 云端的存储,如果此项为 true,表示跳过 备份,不会把照片上传到 云端path: 'images'}
}
- 创建保存数据的容器
constructor(props) {super(props);this.state = {imgURL: 'https://qqqww.com/uploads/avatar.png' // 将来,拍摄的照片路径,会存到这里}}
- 渲染
render() {return <View style={{ alignItems: 'center', paddingTop: 70 }}><Image source={{ uri: this.state.imgURL }} style={{ width: 200, height: 200, borderRadius: 100 }}></Image><Button title="拍照" onPress={this.cameraAction}></Button></View>}
- 定义一个拍照方法,在渲染的时候调用
cameraAction = () => {ImagePicker.showImagePicker(photoOptions, (response) => {console.log('response' + response);if (response.didCancel) { // 点击了取消按钮,此时,用户没有拍照return}// 用户已经拍摄了一张照片了this.setState({imgURL: response.uri});})}
到这一步,在
React-Native项目
中的拍照功能就完成了,并且手机测试成功
6 发布安卓项目
说明:这只是用于测试
react-native
的一部分功能的小demo
,并不能用于实际作用
- 先保证配置了一个正确的RN环境
- 在 cmd 命令行中,运行这一句话
keytool -genkey -v -keystore my-release-key2.keystore -alias my-key-alias2 -keyalg RSA -keysize 2048 -validity 10000
生成签名my-release-key.keystore
表示你一会儿要生成的那个 签名文件的 名称【很重要,包找个小本本记下来】-alias
后面的东西,也很重要,需要找个小本本记下来,这个名称可以根据自己的需求改动my-key-alias
- 当运行找个命令的时候,需要输入一系列的参数,找个口令的密码,【一定要找个小本本记下来】
- 当生成了签名之后,这个签名,默认保存到了自己的用户目录下
C:\Users\liulongbin\my-release-key2.keystore
- 将你的签名证书copy到 android/app目录下。
- 编辑
android
->gradle.properties
文件,在最后,添加如下代码:
MYAPP_RELEASE_STORE_FILE=your keystore filename
MYAPP_RELEASE_KEY_ALIAS=your keystore alias
MYAPP_RELEASE_STORE_PASSWORD=*****
MYAPP_RELEASE_KEY_PASSWORD=*****
- 编辑 android/app/build.gradle文件添加如下代码:
...
android {...defaultConfig { ... }+ signingConfigs {+ release {+ storeFile file(MYAPP_RELEASE_STORE_FILE)+ storePassword MYAPP_RELEASE_STORE_PASSWORD+ keyAlias MYAPP_RELEASE_KEY_ALIAS+ keyPassword MYAPP_RELEASE_KEY_PASSWORD+ }+}buildTypes {release {...+ signingConfig signingConfigs.release}}
}
...
进入项目根目录下的
android
文件夹,在当前目录打开终端,然后输入./gradlew assembleRelease
开始发布APK的Release版;第七步出了点小问题,报错信息是**Execution failed for task ‘:app:validateSigningRelease’.**后来看看原来是我的第五步里的
MYAPP_RELEASE_KEY_ALIAS=your keystore alias
这一块的签名写错了,忘了加后缀名,改了之后,又给了我一个响应超时的惊喜,不过我就重新运行了第二次就打包构建成功了当发行完毕后,进入自己项目的
android\app\build\outputs\apk
目录中,找到app-release.apk
,这就是我们发布完毕之后的完整安装包;安装到自己和朋友的手机上,测试成功,就可以上传到各大应用商店供用户使用啦。
注意:请记得妥善地保管好你的密钥库文件,不要上传到版本库或者其它的地方。
7 参考文章
- ReactNative之Android打包APK方法(趟坑过程)
- React Native发布APP之签名打包APK
ReactNative豆瓣电影项目相关推荐
- ReactNative豆瓣电影项目文档
ReactNative豆瓣电影 欢迎访问我的博客,祝码农同胞们早日走上人生巅峰,迎娶白富美 123456789101112131415161718192021222324252627282930313 ...
- SSR服务器端渲染(Next.js总结和豆瓣电影项目)
一.前言 先解释一下Nuxt.js和Next.js虽然只有一个字母之差,但它们是不同的两个服务端渲染框架. 什么是Next.js? 引用Next中文官网的一句话: Next.js 是一个轻量级的 Re ...
- Tableau豆瓣电影项目实战作业 Day1
作业目标: 1.绘制各国家电影数量条形图(按此命名工作表),要求为横向条形图,按照升序排列,条形图顶部要有标签(要全部显示),选择整个视图将图表充满整个视图区,并给出分析结论: 2.创建电影评分的直方 ...
- Tableau豆瓣电影项目实战作业 Day4
作业目标: 1.制作"2012年各国家电影产量"标靶图,上映时间为2012年,添加参考线和参考分布,参考线为常量--200,参考线颜色为黑色加粗,不显示标签:参考分布选择总量平均值 ...
- Tableau豆瓣电影项目实战作业 Day3
作业目标: 1.制作各国家(产地)电影数量的二值凸显表,以1000为分界,超过1000的数据用红色显示,低于1000的数据用蓝色显示,给出大于1000的电影大国的名称,添加说明导出图像: 2.制作电影 ...
- Tableau豆瓣电影项目实战作业 Day7
作业要求: 1.使用"蒙东地理数据"创建多边形地图,以注释的方式显示每个市的名称,导出图像: 2.使用"2014年各省市售电量"数据,以服务器地图"M ...
- Tableau豆瓣电影项目实战作业 Day9
作业目标: 使用"人工坐席接听数据"完成题目: 1.通过创建计算字段,创建"服务评价满意率"与"人工服务接听量"数据散点图,并将" ...
- react-douban 仿豆瓣电影app项目
前言 A React.js project 一个基于React.js仿豆瓣电影项目(demo),使用react-router.webpack.redux等技术,包含左右滑动,上拉加载更多等功能,数据来 ...
- 爬虫项目之豆瓣电影排行榜前10页
目录 一.学习资源: 二.知识点介绍 1.urlib库的基本使用 2.使用实例 ①获取网页源码 ②从服务器下载网页.图片.视频 3.UA介绍 ①简介 ②实例 三.项目详细讲解 1.分析 2.步骤 ...
最新文章
- Openresty最佳案例 | 第5篇:http和C_json模块
- slz-JDK1.8的环境变量配置
- 滴水课后作业(1-5)
- web中hasmoreelements_Web开发模式【Mode I 和Mode II的介绍、应用案例】
- 单位矩阵属性(I ^ k = I)| 使用Python的线性代数
- java 虚拟内存不够,java虚拟内存不足
- 越烧钱越上瘾,年轻人为何沉迷「白色鸦片」?
- 计算机操作系统(第3版)课后习题答案(完整版)
- 局域网聊天程序 ——灵活使用winsock控件完成局域网数据传输
- 【配置】Pycharm远程连接服务器、配置SSH、配置py环境
- 2021美食林全球餐厅精选榜公布,这里有一份美食地图请查收!
- JS监听鼠标滑轮事件
- java抽象类有什么用_java中抽象类的作用是什么?抽象类作用的例子
- php 开源产品,PHP免费开源企业产品建站系统含手机站
- 一文搞懂异常检测中离群、异常、新类、开集、分布外检测异同
- 惠普HP DesignJet T1708 打印机驱动
- 基于汇编语言实现的带小数的四则运算
- 大数据可精细化推进“供给侧”改革
- 简历造假_深造假的技术对策
- HTML- 超美超简单的相册
热门文章
- 翠翠 Ghost Windows XP SP3 完整全功能纯净版 2013.6.18
- 金融科技之:互联网贷款系统平台建设方案分享
- php taglib.php,thinkphp5 taglib_pre_load预加载自定义标签库
- 修改docker daemon文件
- 纳米科学家在思考什么?
- dx12 龙书第十二章学习笔记 -- 几何着色器
- 基于PCIe的NVMe协议在FPGA中实现方法
- python安装selenium教程
- 零基础学习python(鱼C论坛)
- iOS CollectionView 上拉加载更多