React06
今日内容:
• 路由系统: 实现多页项目
• 网页组件的使用
路由系统
https://www.reactnative.cn/docs/navigation
原生带有路由系统, 但是功能不够强大. 手机端路由通常采用第三方的模块:
https://reactnavigation.org/
使用说明:
https://reactnavigation.org/docs/getting-started
项目下安装支持模块:
npm install @react-navigation/native
npm install react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view
模块的基本结构
安装栈式导航模块
npm install @react-navigation/stack
编译
当有新增模块之后, 必须通过编译操作 把这些模块编译到apk
再运行到模拟器上
npm run android
编译环境不可用的同学, 即 使用ip方式的同学. 把 百度网盘上的压缩包解压缩使用即可.
注意: 必须配对使用!!! 压缩包中的apk 和 压缩包中的项目包
示例Demo
// 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 { createStackNavigator } from '@react-navigation/stack';
function HomeScreen() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
</View>
);
}
const Stack = createStackNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
export default App;
路由跳转
• 跳转
this.props.navigation.push('路由名')
• 传参
this.props.navigation.push('路由名', 参数对象)
• 标题栏配置
– options
– setOptions
• 标题栏按钮
– headerLeft
– headerRight
网页组件
在 RN
中显示网页内容的组件, 需要安装第三方模块
RN
默认提供的 WebView
组件已经被淘汰了. 需要采用第三方
https://github.com/react-native-webview/react-native-webview
安装命令:
必须关闭之前开启的服务, 否则由于项目代码处于占用状态, 会导致无法安装新的模块
npm install react-native-autoheight-webview react-native-webview
重新编译: 当安装了新的模块, 必须重新编译
npm run android
使用百度网盘同学, 就不用编译了.
// 网页组件的使用
// rnc
import React, {Component} from 'react';
import {ScrollView, Text, View} from 'react-native';
// 引入 webview 组件
import {WebView} from 'react-native-webview';
// 自动高度的WebView: 当网页作为页面的一部分出现时, 如果希望网页的高度 与网页内容一样, 则使用另外一款
import AutoHeightWebView from 'react-native-autoheight-webview';
export default class App extends Component {
data = '<h1 style="font-size: 4em">Hello World!</h1>';
render() {
// 网页组件 作为整个页面使用
// return <WebView source={{uri: 'https://www.douyu.com'}} />;
// 本地html: 使用 html 属性名
// return <WebView source={{html: this.data}} />;
//
return (
<ScrollView>
<Text style={{fontSize: 40}}>Hello World!</Text>
{/* 网页组件: 作为页面的一部分使用, 则高度自动缺失, 必须人为指定高度 */}
{/* <WebView
source={{uri: 'https://www.douyu.com'}}
style={{height: 400}}
/> */}
{/* 自动高度的WebView, 高度与内容一样: 必须放在 ScrollView 中使用 */}
{/* 必须放在 ScrollView 中使用 */}
{/* 必须放在 ScrollView 中使用 */}
<AutoHeightWebView source={{uri: 'http://www.bilibili.com'}} />
{/*
如果打包成apk, 则高版本手机需要关闭 硬件加速 选项:
androidHardwareAccelerationDisabled={true}
添加此属性即可
*/}
<Text style={{fontSize: 40}}>Hello World!</Text>
</ScrollView>
);
}
}
横向滚动展示
// 横向滚动展示 banner
// rnc
import React, {Component} from 'react';
import {Dimensions, FlatList, Image, Text, View} from 'react-native';
const {width, height} = Dimensions.get('screen');
function rpx(fs) {
return (width / 750) * fs;
}
export default class App extends Component {
state = {result: []};
componentDidMount() {
let url = 'https://api.apiopen.top/getWangYiNews?page=1';
fetch(url)
.then((res) => res.json())
.then((res) => {
console.log(res);
// 更新操作结束后, 启动定时器: 每2秒滚动一次
// setState(数据项, 成功后的回调)
this.setState({result: res.result}, () => {
//更新UI之后的回调函数
setInterval(() => {
// 滚动到下一张
// console.log(this.fl);
// scrollToIndex(): 滚动到指定序号
// onScroll 时 会自动变更 page, 所以不需要在这里变更 page 的值
if (this.page == this.state.result.length - 1) {
this.fl.scrollToIndex({index: 0});
} else {
this.fl.scrollToIndex({index: this.page + 1});
}
// this.fl.scrollToIndex({index: this.page});
}, 2000);
});
});
}
page = 0; //序号
render() {
/**
* 高性能滚动组件:
* 3个核心属性:
* 1. data: 设定要显示的数据数组
* 2. keyExtractor: 每一条UI的唯一标识
* 3. renderItem: 每条数据对应的UI
*
* 其它属性:
* horizontal: 横向滚动
* pagingEnabled: 按页滚动
* onScroll: 滚动事件
*/
return (
<View>
<FlatList
// ref: 绑定当前标签到一个自定义变量上
// ref触发的箭头函数, 参数就是当前组件, 即 e; 自定义 fl 属性 存储这个e
ref={(e) => (this.fl = e)}
data={this.state.result}
keyExtractor={(item, index) => index + ''}
renderItem={this._renderItem}
horizontal
pagingEnabled
onScroll={this._onScroll}
/>
</View>
);
}
_onScroll = (event) => {
// React的事件是: 合成事件 -- 非DOM 也非虚拟DOM
// 特点: 要想打印看值, 必须调用 event.persist()
// event.persist();
// console.log(event);
let offset_x = event.nativeEvent.contentOffset.x; //横向偏移量
let w = event.nativeEvent.layoutMeasurement.width; //每个的宽
// 偏移量 / 宽 = 当前序号
this.page = Math.round(offset_x / w); // round: 四舍五入为整数
console.log(this.page);
};
_renderItem = ({item, index}) => {
return (
<View>
<Image
source={{uri: item.image}}
style={{width, height: (width * 88) / 140}}
/>
<Text
style={{
fontSize: rpx(37),
width,
backgroundColor: 'rgba(0,0,0,0.5)',
}}>
{item.title}
</Text>
</View>
);
};
}