文章目录
一、顶部导航栏
1、index.js
index.js 引用自定义组件,通过props传递参数
import React, {Component} from 'react';
import TopNavigator from './TopNavigator';
import Game from './components/game';
import Music from './components/music';
import Video from './components/video';
import Main from './components/main';
import LiveStreaming from './components/liveStreaming';
import Recommend from './components/recommend';
import GhostAnimal from './components/ghostAnimal';
import Dance from './components/dance';
import BigData from './components/bigData';
export default class TopNavigationBar extends Component {
render() {
const navigationParams = {
defaultOption: 'game',
options: [
{
key: 'game',
title: '游戏',
selectColor: '#fe56a1',
screen: Game,
},
{
key: 'music',
title: '音乐',
selectColor: '#fe56a1',
screen: Music,
},
{
key: 'video',
title: '影视',
selectColor: '#fe56a1',
screen: Video,
},
{
key: 'main',
title: '首页',
selectColor: '#fe56a1',
screen: Main,
},
{
key: 'liveStreaming',
title: '直播',
selectColor: '#fe56a1',
screen: LiveStreaming,
},
{
key: 'recommend',
title: '推荐',
selectColor: '#fe56a1',
screen: Recommend,
},
{
key: 'ghostAnimal',
title: '鬼畜',
selectColor: '#fe56a1',
screen: GhostAnimal,
},
{
key: 'dance',
title: '舞蹈',
selectColor: '#fe56a1',
screen: Dance,
},
{
key: 'bigData',
title: '大数据',
selectColor: '#fe56a1',
screen: BigData,
},
],
};
return <TopNavigator {...navigationParams}></TopNavigator>;
}
}
2、TopNavigator.js(主要实现)
Navigator.js 自定义导航栏组件
import React, {Component} from 'react';
import {
Text,
View,
StyleSheet,
TouchableOpacity,
SafeAreaView,
ScrollView,
FlatList,
} from 'react-native';
export default class Navigation extends Component {
static defaultProps = {
defaultOption: '', // 默认页
options: [], // 导航栏组件
};
state = {
key: 'Main',
};
componentDidMount() {
const {defaultOption} = this.props;
defaultOption && this.checkPage(defaultOption);
}
// 切换页面
checkPage = key => {
this.setState({key});
};
render() {
const {key} = this.state;
const {options} = this.props;
const cloumnList = ({item}) => (
<TouchableOpacity
onPress={() => this.checkPage(item.key)}
style={
item.key == key
? {...styles.selectBtn, borderColor: item.selectColor}
: styles.btn
}>
<Text
style={
item.key == key
? {...styles.selectBtnTxt, color: item.selectColor}
: styles.btnTxt
}>
{item.title}
</Text>
</TouchableOpacity>
);
return (
<>
{/* 导航栏 */}
<SafeAreaView>
<FlatList
style={styles.btnContent}
// 数据
data={options}
// 数据处理
renderItem={cloumnList}
// 每列的key
keyExtractor={item => item.key}
// 水平布局
horizontal
// 隐藏水平滚动条
showsHorizontalScrollIndicator={false}
/>
</SafeAreaView>
{/* 视图 */}
<SafeAreaView style={styles.box}>
<ScrollView style={styles.viewContent}>
<View style={{backgroundColor: '#f4f4f4'}}>
{options
.filter(item => item.key === key)
.map(nav => React.createElement(nav.screen, {key: nav.key}))}
</View>
</ScrollView>
</SafeAreaView>
</>
);
}
}
const styles = StyleSheet.create({
btnContent: {
backgroundColor: '#fff',
},
btn: {
// 上下内边距
paddingVertical: 5,
// 左右内边距
paddingHorizontal: 5,
// 左右外边距
marginHorizontal: 10,
},
selectBtn: {
paddingVertical: 5,
paddingHorizontal: 5,
marginHorizontal: 10,
borderBottomWidth: 2,
},
btnTxt: {
fontSize: 14,
},
selectBtnTxt: {
fontSize: 15,
fontWeight: 'bold',
},
viewContent: {
padding: 5,
},
box: {
flex: 1,
backgroundColor: '#fff',
},
});
3、最终效果图
最终效果图展示
二、底部导航栏
1、index.js
index.js 引用自定义组件,通过props传递参数
import React, {Component} from 'react';
import Main from './components/Main';
import Dynamic from './components/Dynamic';
import Shop from './components/Shop';
import Mine from './components/Mine';
import Navigator from './navigator';
export default class BottonNavifationBar extends Component {
render() {
const navigatorParams = {
defaultPageKey: 'Main', // 默认页,使用的参数是key
navigator: [
{
key: 'Main', // 页面标识
title: '首页', // 导航栏名称
icon: require('../../resource/main.png'), // 导航栏图片
selectIcon: require('../../resource/main1.png'), // 导航栏选中时的图片
color: '#000', // 文字颜色
selectColor: '#fe56a1', // 导航栏选中时的文字颜色
screen: Main, // 引用组件
},
{
key: 'Dynamic',
title: '动态',
icon: require('../../resource/dynamic.png'),
selectIcon: require('../../resource/dynamic1.png'),
color: '#000',
selectColor: '#fe56a1',
screen: Dynamic,
},
{
key: 'Shop',
title: '商城',
icon: require('../../resource/shop.png'),
selectIcon: require('../../resource/shop1.png'),
color: '#000',
selectColor: '#fe56a1',
screen: Shop,
},
{
key: 'Mine',
title: '我的',
icon: require('../../resource/mine.png'),
selectIcon: require('../../resource/mine1.png'),
color: '#000',
selectColor: '#fe56a1',
screen: Mine,
},
],
};
return <Navigator {...navigatorParams}></Navigator>;
}
}
2、Navigator.js(主要实现)
Navigator.js 自定义导航栏组件,我是起名渣,参数名什么的就随便看看吧,我觉得样式还是挺关键的,不然都摆不出一个好看的页面
import React, {Component} from 'react';
import {
Text,
View,
StyleSheet,
TouchableOpacity,
SafeAreaView,
ScrollView,
Image,
} from 'react-native';
export default class Navigator extends Component {
static defaultProps = {
defaultPageKey: '', // 默认页,使用的key参数
navigator: [], // 导航栏数组
};
state = {
key: 'Main',
};
componentDidMount() {
this.checkNav(this.props.defaultPageKey);
}
// 切换页面
checkNav = key => {
// 设置默认页
this.setState({key});
};
render() {
const {key} = this.state;
const {navigator} = this.props;
return (
<SafeAreaView style={{flex: 1}}>
{/* 视图 */}
<ScrollView style={styles.contentView}>
<View style={styles.content}>
{navigator
.filter(item => item.key === key)
.map(nav => React.createElement(nav.screen, {key: nav.key}))}
</View>
</ScrollView>
{/* 导航栏 */}
<View style={styles.navigationView}>
{navigator.map(item => {
return (
<TouchableOpacity
key={item.key}
style={styles.navBtn}
onPress={() => this.checkNav(item.key)}>
<Image
source={item.key === key ? item.selectIcon : item.icon}
style={styles.btnImg}></Image>
<Text
style={
item.key === key
? {...styles.btnTxt, color: item.selectColor}
: {...styles.btnTxt, color: item.color}
}>
{item.title}
</Text>
</TouchableOpacity>
);
})}
</View>
</SafeAreaView>
);
}
}
// 样式
const styles = StyleSheet.create({
contentView: {
backgroundColor: '#fff',
padding: 10,
},
content: {
flex: 1,
backgroundColor: '#f4f4f4',
},
navigationView: {
backgroundColor: '#fff',
padding: 10,
flexDirection: 'row',
justifyContent: 'space-around',
borderTopWidth: 2,
borderColor: '#f4f4f4',
},
navBtn: {
padding: 20,
},
btnImg: {
width: 35,
height: 35,
},
btnTxt: {
fontSize: 12,
textAlign: 'center',
},
text: {
fontSize: 42,
},
});
3、最终效果图
最终效果图展示 ,顶上的那个标题是我写的路由组件,我把自己的东西都集成在一个地方了,所以这个大家就不用在意了
三、轮播图
1、index.js
import React, {Component} from 'react';
import {
StyleSheet,
Text,
View,
ScrollView,
Image,
Dimensions,
} from 'react-native';
// 引入Dimensions库 - 获取设备宽高
var {width, height} = Dimensions.get('window');
// 这个可以从 接口 或 json文件 获取
const imageData = {
data: [
{
img: require('../../resource/carousel1.jpeg'),
title: '图片一',
},
{
img: require('../../resource/carousel2.jpeg'),
title: '图片二',
},
{
img: require('../../resource/carousel3.jpeg'),
title: '图片三',
},
],
other: [
{
title: '其他信息',
},
],
};
export default class Carousel extends Component {
state = {
currentPage: 0,
};
// 定时器
timer = undefined;
componentDidMount() {
// 加载完毕时开始自动轮播
this.autoPlay();
}
componentWillUnmount() {
// 组件销毁时清除定时器
this.stopPlay();
}
// scrollView子视图
renderItem() {
// 根据json数据实例化视图
let itemAry = imageData.data.map((item, index) => (
<Image key={index} style={styles.itemStyle} source={item.img} />
));
return itemAry;
}
// 分页指示器
renderPagingIndicator() {
const {currentPage} = this.state;
let itemAry = imageData.data.map((item, index) => {
let autoColor =
currentPage == index ? {color: '#fff'} : {color: '#a3a9b9'};
return (
<Text key={index} style={[{fontSize: 30}, autoColor]}>
•
</Text>
);
});
return itemAry;
}
// 监听滚动
onAnimationEnd(e) {
// 求出水平方向上的偏移量
let offSetX = e.nativeEvent.contentOffset.x;
// 计算当前页码
let currentPage = parseInt((offSetX / width).toFixed(0));
this.stopPlay();
// 重新绘制UI
this.setState({currentPage}, () => this.autoPlay());
}
// 切换轮播
checkCarousel = () => {
let {currentPage} = this.state;
if (currentPage + 1 >= imageData.data.length) {
currentPage = 0;
} else {
currentPage++;
}
// console.log(currentPage);
this.scrollView && this.scrollView.scrollTo({x: width * currentPage});
this.setState({currentPage});
};
// 自动轮播
autoPlay = () => (this.timer = setInterval(() => this.checkCarousel(), 3000));
// 停止轮播 / 清除定时器
stopPlay = () => this.timer && clearInterval(this.timer);
render() {
const {currentPage} = this.state;
return (
<>
<View style={styles.container}>
<ScrollView
ref={ref => (this.scrollView = ref)}
style={styles.scrollViewStyle}
horizontal={true} // 水平方向 展示
showsHorizontalScrollIndicator={false} // 隐藏水平指示器
showsVerticalScrollIndicator={false} // 隐藏垂直指示器
pagingEnabled={true} // 开启分页功能
onMomentumScrollEnd={e => this.onAnimationEnd(e)} // 当一帧滚动完毕的时候调用
>
{this.renderItem()}
</ScrollView>
{/* 实例化分页指示器 */}
<View style={styles.pagingIndicatorStyle}>
{this.renderPagingIndicator()}
</View>
</View>
<View>
<Text>这是图片_{currentPage + 1}</Text>
</View>
</>
);
}
}
const styles = StyleSheet.create({
container: {
backgroundColor: '#fff',
},
scrollViewStyle: {
// 背景色
backgroundColor: 'black',
// 上边距
marginTop: 20,
},
itemStyle: {
// 尺寸
width: width,
height: 200,
// 图片等比例拉伸
resizeMode: 'contain',
},
pagingIndicatorStyle: {
// 背景色(使背景色为全透明)
backgroundColor: 'rgba(255,255,255,0.0)',
// 尺寸
width: width,
// 主轴方向与对齐方式
flexDirection: 'row',
justifyContent: 'center',
// 绝对定位,使页码指示器盖在scrollView上面
position: 'absolute',
bottom: 0,
left: width / 3,
},
});