App的分类(按开发方式)
大致可以分为这3种:
-
native app(原生app:ios或安卓)原生应用程序
原生应用程序外观和运行起来(性能)是最佳的。可以访问本地资源,开法成本高。发布审核周期长。 -
web app/ H5 app (APIclound)H5应用程序
整体量级轻,开发成本低,基于浏览器,可以跨平台使用。资源都在远程服务器。网速受到限制时,交互效果也会受到限制,页面跳转费力,不稳定感更强。无法操作很多手机原生设备,摄像头,麦克风,不支持多点触控等。 -
hybrid app(混合app)混合应用程序
集原生应用程序和HTML5应用程序的优点(及缺点)于一体。速度快,跨平台。
ReactNative简介
React Native使你只使用JavaScript也能编写原生移动应用。它在设计原理上和React一致,通过声明式的组件机制来搭建丰富多彩的用户界面。
React Native最终产品很贴近移动应用,从使用感受上和用Objective-C或Java编写的应用相比几乎是无法区分的。React Native所使用的基础UI组件和原生应用完全一致。你要做的就是把这些基础组件使用JavaScript和React的方式组合起来。所以有React基础,那么学习RN会非常轻松。
ReactNative中文官网: https://reactnative.cn/
ReactNative学习
搭建环境
-
创建项目
npx react-native init LifeServices --version 0.55.4
LifeServices为项目名称 -
打包并运行项目
yarn react-native run-android
自定义组件
代码笔记:
index.js:
import { AppRegistry } from 'react-native';
import App from './components/App1';
AppRegistry.registerComponent('AwesomeProject', () => App);
app.js:
// 1、自定义组件
// 1) 引入核心模块
import React, { Component } from "react"
import { View, Text, StyleSheet } from "react-native"
// 2) 创建并导出组件
export default class App1 extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.txt1}>nihoa</Text>
</View>
)
}
}
// 3) 样式代码
const styles = StyleSheet.create({
txt1: {
color: "red"
},
container: {
backgroundColor: "#ccc"
}
})
实现效果:
View组件 - 初步认识ScrollView组件
代码笔记:
app.js:
// 2、 View组件 初步认识ScrollView组件
// 1) 引入核心模块
import React, { Component } from "react"
import { View, Text, StyleSheet, ScrollView } from "react-native"
// 2) 创建并导出组件
export default class App2 extends Component {
render() {
return (
<View style={styles.container}>
{/* View组件默认情况下超出的内容不可见 */}
{/* 把ScrollView加载需要出现滚动条的盒子内部,默认出现的是竖向滚动条 如果要横向添加horizontal属性 <ScrollView horizontal> */}
<ScrollView>
<Text style={styles.txt1}>易烊千玺!!!易烊千玺!!!易烊千玺!!!易烊千玺!!!易烊千玺!!!易烊千玺!!!易烊千玺!!!易烊千玺!!!易烊千玺!!!易烊千玺!!!文字超出不显示!!要用到ScrollView组件!!!</Text>
</ScrollView>
</View>
)
}
}
// 3) 样式代码
const styles = StyleSheet.create({
txt1: {
color: "red"
},
container: {
width: 100,
height: 100,
backgroundColor: "pink"
}
})
实现效果:
获取屏幕的宽高和像素比
代码笔记:
app.js:
// 2、 View组件 初步认识ScrollView组件
import React, { Component } from "react"
import { View, Text, Dimensions } from "react-native"
const { width, height, scale } = Dimensions.get('window')
export default class App3 extends Component {
render() {
return (
<View>
{/* 获取的是可用范围的宽高 */}
<Text>屏幕的宽度是:{width}</Text>
<Text>屏幕的高度是:{height}</Text>
<Text>屏幕的像素比是:{scale}</Text>
</View>
)
}
}
实现效果:
练习题
书写一个满屏的盒子 && 书写一条最细的线
代码笔记:
app.js:
// 4、练习题
// 1) 书写一个满屏的盒子
// 2) 书写一条最细的线(高度最小)
import React, { Component } from "react"
import { View, Text, Dimensions, StyleSheet } from "react-native"
const { width, height, scale } = Dimensions.get('window')
export default class App3 extends Component {
render() {
return (
<View style={styles.container}>
{/* 获取的是可用范围的宽高 */}
<Text>屏幕的宽度是:{width}</Text>
<Text>屏幕的高度是:{height}</Text>
<Text>屏幕的像素比是:{scale}</Text>
<View style={styles.line}></View>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
// width,
// height,
// width: "100%",
// height: "100%",
flex: 1,
backgroundColor: "pink"
},
line: {
// 高 / 像素比
height: 1 / scale,
backgroundColor: "#000"
}
})
实现效果:
Flex布局
与CSS中的Flex布局类似:https://blog.csdn.net/qq_53472371/article/details/120919930
但是React Native要用 flexDirction\ alignItem\ justifyContent
代码笔记:
// 5、flex布局
import React, { Component } from "react"
import { View, Text, StyleSheet } from "react-native"
export default class App5 extends Component {
render() {
return (
<View style={styles.container}>
<View style={styles.box1}><Text style={{ fontSize: 20 }}>1</Text></View>
<View style={styles.box2}><Text style={{ fontSize: 40 }}>2</Text></View>
<View style={styles.box3}><Text style={{ fontSize: 30 }}>3</Text></View>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
display: "flex",
flex: 1,
// 确定哪个是主轴
// flexDirection的4个值:'row', 'row-reverse', 'column', 'column-reverse'
flexDirection: "row",
// 控制主轴对齐方式
// justifyContent的4个值:'flex-start', 'flex-end', 'center', 'space-between', 'space-around'
// justifyContent: "space-between"
justifyContent: 'center',
// 控制侧轴方向的对齐方式
// alignItems的4个值:'flex-start', 'flex-end', 'center', 'stretch', 'baseline'
// 'stretch' 设置侧轴方向上的拉伸,高度没有设置值,才能看到效果(要去掉高度属性)
// 'baseline' 设置基线对齐,设置以文字底部来对齐
// alignItems: 'baseline'
alignItems: 'center'
},
box1: {
width: 100,
height: 100,
backgroundColor: "#ccc"
},
box2: {
width: 100,
height: 100,
backgroundColor: "#fcf"
},
box3: {
width: 100,
height: 100,
backgroundColor: "#ffc"
},
})
Flex布局练习
代码笔记:
// 6、Flex布局练习
import React, { Component } from "react"
import { View, Text, StyleSheet, Dimensions } from "react-native"
const { width, height, scale } = Dimensions.get('window')
// 抽组件
class Row extends Component {
render() {
return (
<View style={styles.row}>
<View style={styles.box1}><Text>1</Text></View>
<View style={styles.box2}><Text>2</Text></View>
<View style={styles.box3}><Text>3</Text></View>
</View>
)
}
}
export default class App6 extends Component {
render() {
return (
<View style={styles.container}>
<Text style={{ fontSize: 18 }}>Flex布局练习</Text>
<View style={styles.boxs}>
<Row />
<Row />
<Row />
</View>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flexDirection: 'column',
alignItems: 'center',
paddingTop: 80
},
boxs: {
width: width * 0.9, // 0.9倍的屏幕宽度
height: 200,
backgroundColor: "#ccc",
marginTop: 10
},
row: {
flex: 1,
borderWidth: 1,
borderColor: "#000",
// 设置主轴方向为水平
flexDirection: "row"
},
box1: {
flex: 1.5,
borderWidth: 1,
borderColor: "#f00",
},
box2: {
flex: 1,
borderWidth: 1,
borderColor: "#f00",
},
box3: {
flex: 2,
borderWidth: 1,
borderColor: "#f00",
}
})
实现效果:
Button按钮组件
代码笔记:
app.js:
// Button按钮组件
import React, { Component } from "react"
import { View, Text, StyleSheet, Button } from "react-native"
export default class App7 extends Component {
constructor(props) {
super(props)
this.state = {
num: 20
}
// this的指向问题
this.handlePress = this.handlePress.bind(this)
}
handlePress() {
// alert(123);
this.setState({
num: this.state.num + 1
})
}
render() {
return (
<View>
<Text>{this.state.num}</Text>
<Button title="按钮中的文本" color="skyblue" onPress={this.handlePress} style={styles.btn}></Button>
</View>
)
}
}
// Button按钮组件不能修改样式!!!
const styles = StyleSheet.create({
btn: {
width: 150,
height: 100
}
})
自定义按钮组件TouchableOpacity
因为Button样式本身有局限性。TouchableOpacity组件可以*定义组件样式。
代码笔记:
app.js:
// Button按钮组件
import React, { Component } from "react"
import { View, Text, StyleSheet, Button, TouchableOpacity } from "react-native"
export default class App7 extends Component {
constructor(props) {
super(props)
this.state = {
num: 20
}
// this的指向问题
this.handlePress = this.handlePress.bind(this)
}
handlePress() {
// alert(123);
this.setState({
num: this.state.num + 1
})
}
render() {
return (
<View>
<Text>{this.state.num}</Text>
<Button title="按钮中的文本" color="skyblue" onPress={this.handlePress} style={styles.btn}></Button>
<TouchableOpacity onPress={this.handlePress} style={styles.btn}><Text>点击自增</Text></TouchableOpacity>
</View>
)
}
}
// Button按钮组件不能修改样式
const styles = StyleSheet.create({
btn: {
width: 100,
height: 100,
backgroundColor: "pink",
borderRadius: 50,
justifyContent: "center",
alignItems: "center"
}
})
实现效果:
Image组件
引入方式:
代码笔记:
// 8、Image组件
import React, { Component } from "react"
import { View, Text, Image, StyleSheet } from "react-native"
import Img from "../res/logo.png"
export default class App5 extends Component {
render() {
return (
<View>
<Text>方式1:</Text>
<Image source={Img} />
<Text>方式2:</Text>
<Image source={require("../res/logo.png")} />
<Text>方式3:</Text>
<Image source={{ uri: "https://img-home.csdnimg.cn/images/20201124032511.png" }} style={styles.img} />
</View>
)
}
}
const styles = StyleSheet.create({
img: {
width: 300,
height: 100
}
})
实现效果:
WebView组件
WebView组件相当于在app内部内嵌一个浏览器,可以通过它的source属性中的uri,写入对应的网页地址,从而展示一个页面。
代码笔记:
// 9、WebView组件
import React, { Component } from "react"
import { WebView } from "react-native"
export default class App9 extends Component {
render() {
return (
<WebView source={{ uri: "https://m.jd.com/" }}></WebView>
)
}
}
图片的另一种引入方式
代码笔记:
// 图片的另一种引入方式
import React, { Component } from "react"
import { View, Image, Text, StyleSheet } from "react-native"
export default class App5 extends Component {
render() {
return (
<View>
<Text>图片的另一种引入方式</Text>
{/* avatar:图片名称 */}
<Image source={{ uri: "avatar" }} style={{ width: 300, height: 100 }} />
</View>
)
}
}
实现效果:
FlatList组件的使用
代码笔记:
// FlatList组件的使用
import React, { Component } from "react"
import { View, FlatList, Text } from "react-native"
const arr_data = [
{
id: 1,
data: 10
},
{
id: 2,
data: 20
},
{
id: 3,
data: 30
},
{
id: 4,
data: 40
},
]
export default class App11 extends Component {
constructor(props) {
super(props)
this.state = {
arr_data
}
}
renderData({ item }) { // 这个函数决定了每一项的展示方式 item就是每一项数据
return (
<Text>{item.id}、{item.data}</Text>
)
}
render() {
return (
<View>
<FlatList
numColumns={1} // 每行显示的个数
data={this.state.arr_data} // 数据源
renderItem={this.renderData}// 渲染函数
/>
</View>
)
}
}
图片展示的练习
代码示例:
import React, { Component } from "react"
import { View, Text, Image, FlatList, StyleSheet } from "react-native"
const img_data = [
{
name: "p01",
des: "111"
},
{
name: "p02",
des: "222"
},
{
name: "p03",
des: "333"
},
{
name: "p04",
des: "444"
},
{
name: "p05",
des: "555"
},
{
name: "p06",
des: "666"
},
]
export default class App5 extends Component {
constructor(props) {
super(props)
this.state = {
img_data
}
}
renderData({ item }) {
return (
<View>
<Image source={{ uri: item.name }} style={styles.imgContent} />
<Text style={styles.txtContent} >{item.des}</Text>
</View>
)
}
render() {
return (
<View style={styles.container}>
<Image source={require("../res/tit_50x16.png")} style={styles.imgTitle} />
<FlatList
numColumns={3} // 每行显示的个数
data={this.state.img_data} // 数据源
renderItem={this.renderData}// 渲染函数
/>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#ccc",
paddingLeft: 10,
paddingRight: 10,
},
imgTitle: {
width: 50,
height: 16,
marginTop: 10,
marginBottom: 10
},
imgContent: {
width: 100,
height: 100,
marginRight: 20
},
txtContent: {
width: 100,
height: 18,
marginBottom: 10
}
})
实现效果:
TextInput组件
代码笔记:
// TextInput组件
import React, { Component } from "react"
import { View, Text, TextInput, StyleSheet } from "react-native"
export default class App5 extends Component {
render() {
return (
<View>
<TextInput style={styles.txtInput}
placeholder="请输入..." // 占位符设置(提示文本)
placeholderTextColor="#ccc" // 占位符颜色设置
maxLength={6} // 可以输入的最大长度
underlineColorAndroid="transparent" // 底线设置透明
// secureTextEntry={true} // 安卓下的密码设置
/>
</View>
)
}
}
const styles = StyleSheet.create({
txtInput: {
borderWidth: 1,
borderColor: "#000",
marginTop: 50,
// 有自带padding 可以去掉padding
padding: 0,
height: 40
}
})
登录界面的实现
代码示例:
import React, { Component } from "react"
import { View, Text, StyleSheet, Dimensions, Image, TextInput, TouchableOpacity } from "react-native"
const { width, height, scale } = Dimensions.get('window')
export default class App14 extends Component {
render() {
return (
<View style={styles.container}>
<View style={styles.wrap}>
{/* 头像 */}
<Image source={require("../res/avatar.jpg")} style={styles.avatar} />
{/* 用户名 */}
{/* 具备多个样式的写法格式:style={[styles.txtInput, styles.username]} */}
<TextInput style={[styles.txtInput, styles.username]}
placeholder="请输入用户名"
placeholderTextColor="#ddd"
underlineColorAndroid="transparent"
/>
{/* 密码 */}
<TextInput style={styles.txtInput}
placeholder="请输入密码"
placeholderTextColor="#ddd"
underlineColorAndroid="transparent"
/>
{/* 登录按钮 */}
<TouchableOpacity style={styles.loginBtn} activeOpacity={0.7}>
{/* 和文字相关的属性,都加在Text组件上(无继承效果) */}
<Text style={styles.loginTxt}>登 录</Text>
</TouchableOpacity>
{/* 忘记密码&&注册新用户 */}
<View style={styles.btns}>
<TouchableOpacity activeOpacity={0.9}>
<Text>忘记密码</Text>
</TouchableOpacity>
<TouchableOpacity activeOpacity={0.9}>
<Text>注册新用户</Text>
</TouchableOpacity>
</View>
{/* 其他方式登录 */}
<View style={styles.bottomBox}>
<View style={styles.line}></View>
<Text style={styles.bottomTxt}>其他方式登录</Text>
<View style={styles.bottomImages}>
<TouchableOpacity activeOpacity={0.9}>
<Image source={require("../res/icon1.png")} style={styles.bottomImage} />
</TouchableOpacity>
<TouchableOpacity activeOpacity={0.9}>
<Image source={require("../res/icon2.png")} style={[styles.bottomImage, styles.bottomImageSnd]} />
</TouchableOpacity>
<TouchableOpacity activeOpacity={0.9}>
<Image source={require("../res/icon3.png")} style={styles.bottomImage} />
</TouchableOpacity>
</View>
</View>
</View>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#eee",
alignItems: "center"
},
wrap: {
width: 320,
height,
// backgroundColor: "#ccc",
alignItems: "center"
},
avatar: {
width: 60,
height: 60,
borderRadius: 30,
borderWidth: 1,
borderColor: "#fff",
marginTop: 50,
marginBottom: 30
},
txtInput: {
width: 320,
height: 40,
backgroundColor: "#fff"
},
username: {
marginBottom: 5
},
loginBtn: {
width: 320,
height: 30,
alignItems: "center",
justifyContent: "center",
backgroundColor: "skyblue",
marginTop: 20,
borderRadius: 4
},
loginTxt: {
color: "#fff"
},
btns: {
width: "100%",
flexDirection: "row",
justifyContent: "space-between",
marginTop: 10
},
line: {
width: "100%",
height: 1 / scale,
backgroundColor: "#999"
},
bottomBox: {
width: "100%",
position: "absolute",
bottom: 40,
alignItems: "center"
},
bottomTxt: {
width: 100,
marginTop: -8,
backgroundColor: "#eee",
textAlign: "center",
fontSize: 12
},
bottomImages: {
flexDirection: "row",
// justifyContent: "center",
marginTop: 10
},
bottomImage: {
width: 40,
height: 40,
borderRadius: 20
},
bottomImageSnd: {
marginLeft: 15,
marginRight: 15
}
})
实现效果:
ScrollView组件的使用
使用ScrollView组件实现横向多屏:
代码示例:
// ScrollView组件的使用
import React, { Component } from "react"
import { View, Text, StyleSheet, Dimensions, ScrollView } from "react-native"
export default class App5 extends Component {
render() {
return (
<View>
<ScrollView
horizontal={true} // 水平排列
pagingEnabled={true} // 滚动条倍数滚动
showsHorizontalScrollIndicator={false} // 不显示横向滚动条(用小圆点代替)
>
<View style={styles.box}><Text>1</Text></View>
<View style={[styles.box, styles.box2]}><Text>2</Text></View>
</ScrollView>
</View>
)
}
}
const styles = StyleSheet.create({
box: {
width: 411,
height: 200,
backgroundColor: "#ccc"
},
box2: {
backgroundColor: "#fcf"
}
})
图片和文字的展示案例
代码示例:
// 图片和文字的展示案例
import React, { Component } from "react"
import { View, Text, StyleSheet, Dimensions, ScrollView, Image } from "react-native"
export default class App5 extends Component {
render() {
return (
<View>
<ScrollView
horizontal={true} // 水平排列
pagingEnabled={true} // 滚动条倍数滚动
showsHorizontalScrollIndicator={false} // 不显示横向滚动条(用小圆点代替)
>
<View style={styles.box}>
<Image source={require("../res/banner1.png")} style={styles.img} />
<Text style={styles.title}>啦啦啦1</Text>
</View>
<View style={styles.box}>
<Image source={require("../res/banner2.png")} style={styles.img} />
<Text style={styles.title}>啦啦啦2</Text>
</View>
<View style={styles.box}>
<Image source={require("../res/banner3.png")} style={styles.img} />
<Text style={styles.title}>啦啦啦3</Text>
</View>
</ScrollView>
</View>
)
}
}
const styles = StyleSheet.create({
box: {
width: 411,
height: 220
},
img: {
width: 411,
height: 220
},
title: {
width: 411,
height: 30,
lineHeight: 30,
backgroundColor: "rgba(0, 0, 0, 0.5)",
position: "absolute",
bottom: 0,
color: "#fff",
paddingLeft: 10
}
})
实现效果:(可滑动)
自动轮播&&无缝滚动效果的实现
代码笔记:
// 自动轮播&&无缝滚动效果
// 原理:当看到第4张图片的时候,瞬间切换到第1张
import React, { Component } from "react"
import { View, Text, StyleSheet, Dimensions, ScrollView, Image } from "react-native"
const { width } = Dimensions.get("window")
export default class App1 extends Component {
componentDidMount() {
let scrollview = this.refs.scrollview // 获取ScrollView组件对象
let num = 0
// 每隔几秒滑动1次
setInterval(() => {
num++;
if (num === 4) { // 多补的这张图片需要被看见,所以num可以等于3
num = 1
// 瞬间切换到第1张(不要带动画效果)
scrollview.scrollTo({ x: 0, y: 0, animated: false })
}
// 在上面判断中已经是第一张,即下一张是第二张,第二张num就应该为1
scrollview.scrollTo({ x: num * width, y: 0, animated: true })
}, 2000);
}
render() {
return (
<View>
<ScrollView
ref="scrollview"
horizontal={true} // 水平排列
pagingEnabled={true} // 滚动条倍数滚动
showsHorizontalScrollIndicator={false} // 不显示横向滚动条(用小圆点代替)
>
<View style={styles.box}>
<Image source={require("../res/banner1.png")} style={styles.img} />
<Text style={styles.title}>啦啦啦1</Text>
</View>
<View style={styles.box}>
<Image source={require("../res/banner2.png")} style={styles.img} />
<Text style={styles.title}>啦啦啦2</Text>
</View>
<View style={styles.box}>
<Image source={require("../res/banner3.png")} style={styles.img} />
<Text style={styles.title}>啦啦啦3</Text>
</View>
<View style={styles.box}>
<Image source={require("../res/banner1.png")} style={styles.img} />
<Text style={styles.title}>啦啦啦1</Text>
</View>
</ScrollView>
</View>
)
}
}
const styles = StyleSheet.create({
box: {
width: 411,
height: 220
},
img: {
width: 411,
height: 220
},
title: {
width: 411,
height: 30,
lineHeight: 30,
backgroundColor: "rgba(0, 0, 0, 0.5)",
position: "absolute",
bottom: 0,
color: "#fff",
paddingLeft: 10
}
})
使用react-native-swiper实现轮播图
基本使用
react-native-swiper:是专门用来实现轮播图的模块
-
安装:
npm i react-native-swiper --save
-
查看:
npm view react-native-swiper
-
删除:
npm rm react-native-swiper --save
代码笔记:
// 使用react-native-swiper实现轮播图
import React, { Component } from "react"
import { View, Text, StyleSheet, Dimensions } from "react-native"
import Swiper from "react-native-swiper"
const { width, height, scale } = Dimensions.get('window')
export default class App3 extends Component {
render() {
return (
<View style={styles.container}>
<Swiper style={styles.wrapper} horizontal={true} autoplay autoplayTimeout={2} showsButtons={true} showsPagination={false}>
<View style={styles.slide1}>
<Text style={styles.text}>hhh</Text>
</View>
<View style={styles.slide2}>
<Text style={styles.text}>lll</Text>
</View>
<View style={styles.slide3}>
<Text style={styles.text}>yyy</Text>
</View>
</Swiper>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
height: 200,
},
wrapper: {
},
slide: {
flex: 1,
justifyContent: "center",
backgroundColor: "transparent"
},
slide1: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#9DD6EB"
},
slide2: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#fcc"
},
slide3: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#cff"
},
text: {
color: "#fff",
fontSize: 30,
fontWeight: "bold"
}
})
实现效果:
实现轮播图
代码示例:
// 使用react-native-swiper实现完整的轮播图(加入图片)
import React, { Component } from "react"
import { View, Text, StyleSheet, Image } from "react-native"
import Swiper from "react-native-swiper"
export default class App4 extends Component {
render() {
return (
<View style={styles.container}>
<Swiper style={styles.wrapper}
horizontal={true}
autoplay
autoplayTimeout={2}
// showsButtons={true}
// showsPagination={false}
dot={<View style={{ backgroundColor: "#ccc", width: 8, height: 8, borderRadius: 4, marginLeft: 3, marginRight: 3, marginTop: 3, marginBottom: 3 }} />}
activeDot={<View style={{ backgroundColor: "yellow", width: 8, height: 8, borderRadius: 4, marginLeft: 3, marginRight: 3, marginTop: 3, marginBottom: 3 }} />}
paginationStyle={{
bottom: 5, left: null, right: 10
}}
>
<View style={styles.slide1}>
<Image source={require("../res/banner1.png")} style={styles.img} />
<Text style={styles.title}>啦啦啦1</Text>
</View>
<View style={styles.slide2}>
<Image source={require("../res/banner2.png")} style={styles.img} />
<Text style={styles.title}>啦啦啦1</Text>
</View>
<View style={styles.slide3}>
<Image source={require("../res/banner3.png")} style={styles.img} />
<Text style={styles.title}>啦啦啦1</Text>
</View>
</Swiper>
</View >
)
}
}
const styles = StyleSheet.create({
container: {
height: 200,
},
wrapper: {
},
slide: {
flex: 1,
justifyContent: "center",
backgroundColor: "transparent"
},
slide1: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#9DD6EB"
},
slide2: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#fcc"
},
slide3: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#cff"
},
img: {
width: 411,
height: 220
},
title: {
width: 411,
height: 30,
lineHeight: 30,
backgroundColor: "rgba(0, 0, 0, 0.5)",
position: "absolute",
bottom: 0,
color: "#fff",
paddingLeft: 10
}
})
实现效果:
适配其他分辨率的做法
每种机型的Dimensions宽度、高度、像素比是有可能不一样的。
关闭所有黄色警告的代码
index.js:
import { AppRegistry } from 'react-native';
import App from './components/App16';
// 关闭全部黄色警告
console.ignoredYellowBox = ['Warning: BackAndroid is deprecated. Please use BackHandler instead.', 'source.uri should not be an empty string', 'Invalid props.style key'];
console.disableYellowBox = true
AppRegistry.registerComponent('AwesomeProject', () => App);
stackNavigator组件
stackNavigator的基本使用
代码笔记:
Page1.js:
import React, { Component } from "react"
import { View, Text, StyleSheet } from "react-native"
export default class Page1 extends Component {
render() {
return (
<View>
<Text>page1</Text>
</View>
)
}
}
App.js:
import React, { Component } from "react"
import { View, Text, StyleSheet, Button } from "react-native"
import { StackNavigator } from "react-navigation"
import Page1 from "./pages/Page1"
class Home extends Component {
render() {
return (
<View>
<Button title="点击跳转到Page1" onPress={() => this.props.navigation.navigate("Page1")} />
</View>
)
}
}
export default StackNavigator({
Home: {
screen: Home, // 对应组件
},
Page1: {
screen: Page1, // 对应组件
}
}, {
headerMode: "none" // 隐藏顶部的导航栏
})
stackNavigator的传参使用和返回
代码笔记:
App.js:
import React, { Component } from "react"
import { View, Text, StyleSheet, Button } from "react-native"
import { StackNavigator } from "react-navigation"
import Page2 from "./pages/Page2"
class Home extends Component {
render() {
return (
<View>
{/* <Button title="点击跳转到Page2" onPress={() => this.props.navigation.navigate("Page2")} /> */}
<Text>这是Home页面</Text>
<Text onPress={() => this.props.navigation.navigate("Page2", { name: "yyqx" })}>点击跳转到Page2</Text>
</View>
)
}
}
export default StackNavigator({
Home: {
screen: Home, // 对应组件
},
Page2: {
path: "page2/:name",
screen: Page2, // 对应组件
}
}, {
headerMode: "none" // 隐藏顶部的导航栏
})
Page2.js:
import React, { Component } from "react"
import { View, Text, StyleSheet, Button } from "react-native"
export default class Page2 extends Component {
render() {
const { navigation } = this.props
return (
<View>
<Text>Page2</Text>
<Text>接收到的参数为:{navigation.state.params.name}</Text>
<Button title="返回Home页面" onPress={() => { navigation.goBack() }} />
</View>
)
}
}
stackNavigator的一些样式配置
代码笔记:
// stackNavigator配置项
import React, { Component } from "react"
import { View, Text, StyleSheet, Button } from "react-native"
import { StackNavigator } from "react-navigation"
import Page1 from "./pages/Page1"
class Home extends Component {
render() {
return (
<View>
<Button title="点击跳转到Page1" onPress={() => this.props.navigation.navigate("Page1")} />
</View>
)
}
}
export default StackNavigator({
Home: {
screen: Home, // 对应组件
navigationOptions: {
title: "Home首页"
}
},
Page1: {
screen: Page1, // 对应组件
navigationOptions: {
// header: null
headerStyle: {
backgroundColor: "#fcf",
height: 40
},
headerTitleStyle: {
color: "#333"
}
}
}
}, {
// 全局的配置
navigationOptions: {
title: "默认界面标题",
headerStyle: {
backgroundColor: "#f40",
height: 40
},
headerTitleStyle: {
color: "#fff"
}
}
})
实现效果:
DrawerNavigator组件
DrawerNavigator的基本使用(打开抽屉)
DrawerNavigator组件可以用来制作抽屉类型的导航,也可以用来制作自定义内容的抽屉。
点击函数中通过:this.props.navigation.openDrawer()
打开抽屉。
代码笔记:
App.js:
// DrawerNavigator的基本使用
import React, { Component } from 'react'
import { Button, View } from 'react-native'
import { DrawerNavigator } from "react-navigation"
class Home extends Component {
render() {
return (
<View>
{/* this.props.navigation.openDrawer() 打开抽屉 */}
<Button title="点击打开抽屉" onPress={() => { this.props.navigation.openDrawer() }} />
</View>
)
}
}
export default DrawerNavigator({
Home: {
screen: Home
}
})
实现效果:
DrawerNavigator的核心使用
代码笔记:
// DrawerNavigator的核心使用
import React, { Component } from 'react'
import { Button, View, Text } from 'react-native'
import { DrawerNavigator } from "react-navigation"
class Home extends Component {
render() {
return (
<View>
{/* this.props.navigation.openDrawer() 打开抽屉 */}
<Button title="点击打开抽屉" onPress={() => { this.props.navigation.openDrawer() }} />
</View>
)
}
}
class Page1 extends Component {
render() {
return (
<View>
<Text>这里是Page1</Text>
<Button title="点击返回" onPress={() => { this.props.navigation.goBack() }} />
</View>
)
}
}
class Page2 extends Component {
render() {
return (
<View>
<Text>这里是Page2</Text>
<Button title="点击返回" onPress={() => { this.props.navigation.goBack() }} />
</View>
)
}
}
export default DrawerNavigator({
Home: {
screen: Home
},
Page1: {
screen: Page1
},
Page2: {
screen: Page2
},
})
实现效果:
DrawerNavigator的一些配置,以及自定义抽屉内容
代码笔记:
// DrawerNavigator的一些配置,以及自定义抽屉内容
import React, { Component } from 'react'
import { Button, View, Text, ScrollView } from 'react-native'
import { DrawerItems, DrawerNavigator, SafeAreaView } from "react-navigation"
class Home extends Component {
render() {
return (
<View>
{/* this.props.navigation.openDrawer() 打开抽屉 */}
<Button title="点击打开抽屉" onPress={() => { this.props.navigation.openDrawer() }} />
</View>
)
}
}
class Page1 extends Component {
render() {
return (
<View>
<Text>这里是Page1</Text>
<Button title="点击返回" onPress={() => { this.props.navigation.goBack() }} />
</View>
)
}
}
export default DrawerNavigator({
Home: {
screen: Home
},
Page1: {
screen: Page1
}
}, {
drawerWidth: 200,
drawerPosition: "right",
// 自定义
contentComponent: (props) => (
<ScrollView style={{ backgroundColor: "#ccc", flex: 1 }}>
{/* <SafeAreaView forceInset={{ top: "always", horizontal: "never" }}>
<DrawerItems {...props} />
</SafeAreaView> */}
<Text>设置其他组件</Text>
</ScrollView>
)
})
实现效果:
从自定义抽屉中传递参数到页面
代码笔记:
// DrawerNavigator 从自定义抽屉向页面传递参数
import React, { Component } from 'react'
import { Button, View, Text, ScrollView } from 'react-native'
import { DrawerItems, DrawerNavigator, SafeAreaView } from "react-navigation"
class Home extends Component {
render() {
return (
<View>
{/* this.props.navigation.openDrawer() 打开抽屉 */}
<Button title="点击打开抽屉" onPress={() => { this.props.navigation.openDrawer() }} />
</View>
)
}
}
class Page1 extends Component {
render() {
const { navigation } = this.props
return (
<View>
<Text>这里是Page1</Text>
<Button title="点击返回" onPress={() => { this.props.navigation.goBack() }} />
<Text>收到的参数为:{navigation.state.params.name}</Text>
</View>
)
}
}
export default DrawerNavigator({
Home: {
screen: Home
},
Page1: {
screen: Page1
}
}, {
drawerWidth: 200,
drawerPosition: "right",
// 自定义
contentComponent: (props) => (
<ScrollView style={{ backgroundColor: "#ccc", flex: 1 }}>
{/* <SafeAreaView forceInset={{ top: "always", horizontal: "never" }}>
<DrawerItems {...props} />
</SafeAreaView> */}
<Button
title="点击跳转到Page1"
onPress={() => props.navigation.navigate("Page1", { name: "yyqx" })}
/>
</ScrollView>
)
})
实现效果:
使用FlatList组件实现下拉刷新
》》》要学会思路!!!
代码笔记:
// 使用FlatList组件实现下拉刷新
import React, { Component } from 'react'
import { FlatList, View, Text, StyleSheet } from 'react-native'
const CITY_NAMES = ["北京市", "上海市", "深圳市", "广州市", "成都", "杭州"]
export default class App extends Component {
constructor(props) {
super(props)
this.state = {
isLoading: false,
dataArr: CITY_NAMES
}
}
renderData({ item }) {
return (
<View style={styles.itemBox}>
<Text style={styles.itemTxt}>{item}</Text>
</View>
)
}
loadData() {
// 1、修改isLoading的值为true
this.setState({
isLoading: true
})
// 2、模拟异步请求
setTimeout(() => {
let newData = CITY_NAMES.reverse() // 把数组反转,模拟新的数据的获取
this.setState({
dataArr: newData,
isLoading: false
})
}, 1000);
}
render() {
return (
<View>
<FlatList
// numColumns=
data={this.state.dataArr}
renderItem={this.renderData}
refreshing={this.state.isLoading} // 设置是否正在加载数据
onRefresh={this.loadData.bind(this)} // 设置刷新的时候执行的代码
/>
</View>
)
}
}
const styles = StyleSheet.create(
{
itemBox: {
width: 360,
height: 200,
backgroundColor: "#ccc",
marginLeft: 20,
marginBottom: 15
},
itemTxt: {
textAlign: "center",
lineHeight: 200
}
}
)
实现效果:
使用FlatList组件实现滑动到底部加载更多(上拉加载更多)
代码笔记:
// 使用FlatList组件实现下拉刷新
import React, { Component } from 'react'
import { FlatList, View, Text, StyleSheet, ActivityIndicator } from 'react-native'
const CITY_NAMES = ["北京市", "上海市", "深圳市", "广州市"]
export default class App extends Component {
constructor(props) {
super(props)
this.state = {
isLoading: false,
dataArr: CITY_NAMES
}
}
renderData({ item }) {
return (
<View style={styles.itemBox}>
<Text style={styles.itemTxt}>{item}</Text>
</View>
)
}
loadData() {
// 1、修改isLoading的值为true
this.setState({
isLoading: true
})
// 2、模拟异步请求
setTimeout(() => {
let newData = this.state.dataArr.concat(CITY_NAMES) // 合并,数据变长
this.setState({
dataArr: newData,
isLoading: false
})
}, 1000);
}
genIndicator() { // 加载符号的制作
return (
<View>
<ActivityIndicator
size="large"
animating={true}
color="#ccc"
/>
<Text style={{ textAlign: "center", flex: 1, marginBottom: 10 }}>正在加载数据...</Text>
</View>
)
}
render() {
return (
<View>
<FlatList
// numColumns=
data={this.state.dataArr}
renderItem={this.renderData}
ListFooterComponent={this.genIndicator} // 确定加载的符号
onEndReached={this.loadData.bind(this)}
/>
</View>
)
}
}
const styles = StyleSheet.create(
{
itemBox: {
width: 360,
height: 200,
backgroundColor: "#ccc",
marginLeft: 20,
marginBottom: 15
},
itemTxt: {
textAlign: "center",
lineHeight: 200
}
}
)
实现效果:
AsyncStorage的使用
代码笔记:
// AsyncStorage存储
import React, { Component } from 'react'
import { AsyncStorage, Button, TextInput, View } from 'react-native'
export default class App14 extends Component {
constructor(props) {
super(props)
this.state = {
val: ""
}
}
handleChange(text) {
this.setState({
val: text
})
}
// handPress() {
// alert(this.state.val)
// }
save() {
AsyncStorage.setItem("key", this.state.val, (error) => {
if (!error) {
alert("保存成功")
} else {
alert("保存失败")
}
})
}
get() {
AsyncStorage.getItem("key", (error, result) => {
if (!error) {
alert("获取成功,值为:" + result)
} else {
alert("获取失败")
}
})
}
remove() {
AsyncStorage.removeItem("key", (error) => {
if (!error) {
alert("删除成功")
} else {
alert("删除失败")
}
})
}
render() {
return (
<View>
<TextInput placeholder="请输入..." onChangeText={this.handleChange.bind(this)} />
{/* <Button title="获取value" onPress={this.handPress.bind(this)} /> */}
<Button title="保存数据" onPress={this.save.bind(this)} />
<Button title="获取数据" onPress={this.get} />
<Button title="删除数据" onPress={this.remove} />
</View>
)
}
}
实现效果:
React Native项目
项目文件夹
导航页面的初步实现(TabNavigator)
在项目中获取周边数据
项目目录下安装axios:yarn add axios@0.18.0