多列布局
// rnc react native component
import React, {Component} from 'react';
// 组件或者API使用时,需要提前导入
import {Text, View, FlatList, Dimensions, Image} from 'react-native';
// 获取屏幕的宽高
const {height, width} = Dimensions.get('window');
// rpx换算为物理像素 使用方法 例如:30rpx rpx(30)
const rpx = x => (width / 750) * x;
export default class App extends Component {
// 实现一个加载网络请求获取数据,并显示到页面 需要经过以下步骤:
// 发送请求 接收数据 存本地 做展示
// 页面上数据 需要发生改变 一般存储在组件状态中 state
state = {result: []};
// 挂在时触发
componentDidMount() {
// 发送请求
const url = 'https://api.apiopen.top/getWangYiNews';
// 发送请求 JS代码 早期xmlHttpRequest
// 新的webAPI 建议使用Fetch
fetch(url)
.then(res => res.json())
.then(data => {
console.log(data);
this.setState({result: data.result});
});
}
render() {
return (
<FlatList
data={this.state.result}
keyExtractor={(item, index) => index}
renderItem={this._renderItem}
// 列数
numColumns={2}
// 每行的样式 多列布局使用
columnWrapperStyle={{
justifyContent:'space-evenly',
marginTop:rpx(10)
}}
></FlatList>
);
}
_renderItem = ({item}) => (
// 计算每个元素的宽度 rpx
// 每个块填充10 两个边 总共4个
// 750-10*4 710/2
// 355
<View style={{width:rpx(355)}}>
<Image
source={{uri: item.image}}
style={{width: '100%', height: rpx(200),borderRadius:rpx(10)}}></Image>
<Text style={{fontSize: rpx(30), padding: rpx(10)}}>{item.title}</Text>
</View>
);
}
实现滚动效果
// rnc
/***
* 横向滚动展示 通过FlatList实现轮播效果
*
*
*/
import React, {Component} from 'react';
import {Text, View, Dimensions, FlatList, Image} from 'react-native';
// rpx计算
const rpx = x => (Dimensions.get('window').width / 750) * x;
export default class App extends Component {
banners = [
'http://www.codeboy.com:9999/img/index/banner1.png',
'http://www.codeboy.com:9999/img/index/banner2.png',
'http://www.codeboy.com:9999/img/index/banner3.png',
'http://www.codeboy.com:9999/img/index/banner4.png',
];
// 挂在时触发
componentDidMount() {
// 启动一个定时器 实现自动滚动
setInterval(() => {
// 下一张
this.current++;
// 判断 越界情况 重置为0
if (this.current == this.banners.length) this.current = 0;
// 调用FlatList的滚动到指定位置方法
this.f1.scrollToIndex({index: this.current});
}, 2500);
}
render() {
return (
<FlatList
data={this.banners}
keyExtractor={(item, index) => index}
renderItem={this._renderItem}
// 横向排列
horizontal
// 按页滚动
pagingEnabled
// 监控滚动
onScroll={this._onScroll}
// ref绑定 需要调用FlatList提供到的方法
// 当前组件类中 this.f1就代表FlatList组件对象
ref={el => (this.f1 = el)}></FlatList>
);
}
// 默认滚动第一个 下标为0
current = 0;
_onScroll = e => {
// RN的事件经过特殊处理,如果打印需要先执行persist
// e.persist();
// console.log(e.nativeEvent.contentOffset.x);
// 滚动过程中 滚动的距离 偏移量
const offset_x = e.nativeEvent.contentOffset.x;
// 滚动的位置的宽度
const w = e.nativeEvent.layoutMeasurement.width;
// 滚动的偏移量/滚动位置的宽度 计算出滚动的是第几个 第几页
// console.log(offset_x / w);
// 后续滚动 是按页滚动的 取整
this.current = Math.round(offset_x / w);
};
_renderItem = ({item}) => (
<Image
source={{uri: item}}
style={{width: rpx(750), height: rpx(300)}}></Image>
);
}
ReactNative路由
- react提供了router路由
- roact-router-dom ReactNative为了能够在移动端有更好的使用体验,专门开发了针对RN的路由系统。
- 官方网址:https://reactnavigation.org/
①生成几个测试页面
在页面中写入基础结构和识别内容,一定要生成组件结构,否则路由切换报错
import React, { Component } from 'react'
import { Text, View } from 'react-native'
export default class APage extends Component {
render() {
return (
<View>
<Text style={{fontSize:30}}> C页面 </Text>
</View>
)
}
}
App.js
// In App.js in a new project
import * as React from 'react';
import {View, Text} from 'react-native';
// 路由容器
import {NavigationContainer} from '@react-navigation/native';
// 栈式导航
import {createNativeStackNavigator} from '@react-navigation/native-stack';
// 1.引入页面组件
import APage from './pages/APage';
import BPage from './pages/BPage';
import CPage from './pages/CPage';
import DPage from './pages/DPage';
// 函数组件
function HomeScreen() {
return (
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<Text>Home Screen</Text>
</View>
);
}
// 创建一个栈式导航
const Stack = createNativeStackNavigator();
// 应用根组件
function App() {
return (
// 最外层包裹一个路由容器
<NavigationContainer>
{/* 栈式导航 */}
<Stack.Navigator>
{/* 组件和路由名称的匹配对应关系 */}
{/* name 路由名称 */}
{/* component 组件名称 */}
{/* 默认加载第一个Stack.Screen */}
{/* <Stack.Screen name="Home" component={HomeScreen} /> */}
{/* options 可定制属性 */}
{/* 参数说明文档:https://reactnavigation.org/docs/native-stack-navigator#options */}
<Stack.Screen
name="A"
component={APage}
options={{
headerTitle: '首页',
headerStyle: {backgroundColor: 'orangered'},
headerTitleStyle: {color: 'white'},
}}></Stack.Screen>
<Stack.Screen name="B" component={BPage}></Stack.Screen>
<Stack.Screen name="C" component={CPage}></Stack.Screen>
<Stack.Screen name="D" component={DPage}></Stack.Screen>
</Stack.Navigator>
</NavigationContainer>
);
}
export default App;
pages\APage.js
import React, {Component} from 'react';
import {Text, View, TouchableOpacity, StyleSheet} from 'react-native';
/**
* 路由会向组件props注入两个属性
* 1.navigation 包含操作路由的方法 跳转方法
* 2.route 包含了路由的相关参数
*
*/
export default class APage extends Component {
render() {
// 解构出跳转方法
const {push} = this.props.navigation;
// push('路由名称')
return (
<View style={{justifyContent: 'center', alignItems: 'center'}}>
<TouchableOpacity
activeOpacity={0.7}
style={ss.btn}
onPress={() => push('B')}>
<Text style={{fontSize: 30, color: 'white'}}>跳转到B页面</Text>
</TouchableOpacity>
<TouchableOpacity
activeOpacity={0.7}
style={ss.btn}
onPress={() => push('C')}>
<Text style={{fontSize: 30, color: 'white'}}>跳转到C页面</Text>
</TouchableOpacity>
{/* 参数传递 通过push方法的第二个参数 */}
<TouchableOpacity
activeOpacity={0.7}
style={ss.btn}
onPress={() => push('D',{name:'JavaScript',msg:'JavaScript是React的基础'})}>
<Text style={{fontSize: 30, color: 'white'}}>跳转到D页面</Text>
</TouchableOpacity>
</View>
);
}
}
const ss = StyleSheet.create({
btn: {
backgroundColor: '#007acc',
padding: 10,
marginTop:10
},
});
pages\DPage.js
import React, {Component} from 'react';
import {Text, View} from 'react-native';
export default class DPage extends Component {
// 组件挂在时
componentDidMount() {
// 获取路由参数
// console.log(this.props);
// const {name, msg} = this.props.route.params;
// console.log('name:',name);
// console.log('msg:',msg);
}
render() {
const {name, msg} = this.props.route.params;
return (
<View>
<Text style={{fontSize: 30}}> D页面 </Text>
<Text style={{fontSize: 30}}>name:{name}</Text>
<Text style={{fontSize: 30}}>msg:{msg}</Text>
</View>
);
}
}