React Native之react-native-scrollable-tab-view详解

前端之家收集整理的这篇文章主要介绍了React Native之react-native-scrollable-tab-view详解前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

在React Native开发中,官方为我们提供的Tab控制器有两种:TabBarIOS和ViewPagerAndroid。TabBarIOS,仅适用于IOS平台
ViewPagerAndroid,仅适用于Android平台(严格来讲并不算,因为我们还需要自己实现Tab)。在项目开发中,我们优先选择一些开源兼容性比较好的第三方库,例如,react-navigation,以及本文即将说到的react-native-scrollable-tab-view(官方地址)。react-native-scrollable-tab-view不仅可以实现顶部的Tab切换,还能实现底部的切换。

我们再来看一下官方的Demo。

属性方法介绍

1, renderTabBar(Function:ReactComponent)

TabBar的样式,系统提供了两种默认的,分别是DefaultTabBar和ScrollableTabBar。当然,我们也可以自定义一个,我们会在下篇文章重点讲解如何去自定义TabBar样式。
注意:每个被包含的子视图需要使用tabLabel属性,表示对应Tab显示文字
DefaultTabBar:Tab会平分在水平方向的空间。
ScrollableTabBar:Tab可以超过屏幕范围,滚动可以显示

  1. render() {
  2. return (
  3. <ScrollableTabView renderTabBar={() => <DefaultTabBar/>}>
  4. <Text tabLabel='Tab1'/>
  5. <Text tabLabel='Tab2'/>
  6. <Text tabLabel='Tab3'/>
  7. <Text tabLabel='Tab4'/>
  8. <Text tabLabel='Tab5'/>
  9. <Text tabLabel='Tab6'/>
  10. </ScrollableTabView>
  11. );
  12. }

2,tabBarPosition(String,默认值’top’)
top:位于屏幕顶部
bottom:位于屏幕底部
overlayTop:位于屏幕顶部,悬浮在内容视图之上(看颜色区分:视图有颜色,Tab栏没有颜色)
overlayBottom:位于屏幕底部,悬浮在内容视图之上(看颜色区分:视图有颜色,Tab栏没有颜色)

  1. render() {
  2. return (
  3. <ScrollableTabView
  4. tabBarPosition='top'
  5. renderTabBar={() => <DefaultTabBar/>}>
  6. ...
  7. </ScrollableTabView>
  8. );
  9. }

3, onChangeTab(Function)
Tab切换之后会触发此方法,包含一个参数(Object类型),这个对象有两个参数:
i:被选中的Tab的下标(从0开始)
ref:被选中的Tab对象(基本用不到)

  1. render() {
  2. return (
  3. <ScrollableTabView
  4. renderTabBar={() => <DefaultTabBar/>}
  5. onChangeTab={(obj) => {
  6. console.log('index:' + obj.i);
  7. }
  8. }>
  9. ...
  10. </ScrollableTabView>
  11. );
  12. }

4,onScroll(Function)
视图正在滑动的时候触发此方法,包含一个Float类型的数字,范围是[0,tab的数量-1]

  1. render() {
  2. return (
  3. <ScrollableTabView
  4. renderTabBar={() => <DefaultTabBar/>}
  5. onScroll={(postion) => {
  6. // float类型 [0,tab数量-1]
  7. console.log('scroll position:' + postion);
  8. }
  9. }>
  10. ...
  11. </ScrollableTabView>
  12. );
  13. }

5, locked(Bool,默认为false)
表示手指是否能拖动视图,默认为false(表示可以拖动)。设为true的话,我们只能“点击”Tab来切换视图。

  1. render() {
  2. return (
  3. <ScrollableTabView
  4. locked={false}
  5. renderTabBar={() => <DefaultTabBar/>}>
  6. ...
  7. </ScrollableTabView>
  8. );
  9. }

6, initialPage(Integer)
初始化时被选中的Tab下标,默认是0(即第一页)。

  1. render() {
  2. return (
  3. <ScrollableTabView
  4. initialPage={1}
  5. renderTabBar={() => <DefaultTabBar/>}>
  6. ...
  7. </ScrollableTabView>
  8. );
  9. }

7,page(Integer)
设置选中指定的Tab。

8,children(ReactComponents)
表示所有子视图的数组,比如下面的代码,children则是一个长度为6的数组,元素类型为Text。

  1. render() {
  2. return (
  3. <ScrollableTabView renderTabBar={() => <DefaultTabBar/>}>
  4. <Text tabLabel='Tab1'/>
  5. <Text tabLabel='Tab2'/>
  6. <Text tabLabel='Tab3'/>
  7. <Text tabLabel='Tab4'/>
  8. <Text tabLabel='Tab5'/>
  9. <Text tabLabel='Tab6'/>
  10. </ScrollableTabView>
  11. );
  12. }

9,tabBarUnderlineStyle(style)
设置DefaultTabBar和ScrollableTabBarTab选中时下方横线的颜 色。
10.,tabBarBackgroundColor(String)
设置整个Tab这一栏的背景颜色
11,tabBarActiveTextColor(String)
设置选中Tab的文字颜色。
12,tabBarInactiveTextColor(String)
设置未选中Tab的文字颜色。
13,contentProps(Object)
这里要稍微说下react-native-scrollable-tab-view的实现,其实在Android平台底层用的是ViewPagerAndroid,iOS平台用的是ScrollView。这个属性的意义是:比如我们设置了某个属性,最后这个属性会被应用在ScrollView/ViewPagerAndroid,这样会覆盖库里面默认的,通常官方不建议我们去使用。
14,scrollWithoutAnimation(Bool,默认为false)
设置“点击”Tab时,视图切换是否有动画,默认为false(即:有动画效果)。

  1. render() {
  2. return (
  3. <ScrollableTabView
  4. scrollWithoutAnimation={true}
  5. renderTabBar={() => <DefaultTabBar/>}>
  6. ...
  7. </ScrollableTabView>
  8. );
  9. }

顶部导航示例

顶部导航的代码是比较简单的。例如,我们实现上图的新闻Tab导航的效果

相关代码

  1. /** * Sample React Native App * https://github.com/facebook/react-native * @flow */
  2.  
  3. import React,{ Component } from 'react';
  4. import ScrollableTabView,{DefaultTabBar,ScrollableTabBar} from 'react-native-scrollable-tab-view';
  5. import {
  6. AppRegistry,StyleSheet,Text,Image,View
  7. } from 'react-native';
  8.  
  9. var Dimensions = require('Dimensions');
  10. var ScreenWidth = Dimensions.get('window').width;
  11.  
  12. class TabTopView extends Component {
  13. render() {
  14. return (
  15. <ScrollableTabView
  16. style={styles.container}
  17. renderTabBar={() => <DefaultTabBar />}
  18. tabBarUnderlineStyle={styles.lineStyle}
  19. tabBarActiveTextColor='#FF0000'>
  20.  
  21. <Text style={styles.textStyle} tabLabel='娱乐'>娱乐</Text>
  22. <Text style={styles.textStyle} tabLabel='科技'>科技</Text>
  23. <Text style={styles.textStyle} tabLabel='军事'>军事</Text>
  24. <Text style={styles.textStyle} tabLabel='体育'>体育</Text>
  25. </ScrollableTabView>
  26. );
  27. }
  28. }
  29.  
  30.  
  31. const styles = StyleSheet.create({
  32. container: {
  33. flex: 1,marginTop: 20
  34. },lineStyle: {
  35. width:ScreenWidth/4,height: 2,backgroundColor: '#FF0000',},textStyle: {
  36. flex: 1,fontSize:20,marginTop:20,textAlign:'center',});
  37.  
  38. export default TabTopView;

然后在index.ios.js或index.android.js中导入组件。

  1. export default class RNDemo extends Component {
  2. render() {
  3. return (
  4. <TabBottomView/>
  5. );
  6. }
  7. }

底部Tab切换示例

需要注意的是项目中用到了Navigator这个组件,在最新的版本中,系统标识Navigator已经过时被抛弃,所以我们需要使用命令先按照相关的库:

  1. npm install --save react-native-deprecated-custom-components

然后在使用的界面中导入Navigator。

  1. import {
  2. Navigator,} from 'react-native-deprecated-custom-components';

好了其他的不再说明,直接上代码
TabBottomView.js

  1. /**
  2. * Sample React Native App
  3. * https://github.com/facebook/react-native
  4. * @flow
  5. */
  6.  
  7. import React,{Component} from 'react';
  8. import {
  9. Navigator,} from 'react-native-deprecated-custom-components';
  10.  
  11. import TabBarView from './TabBarView'
  12. import TabDefaultView from './TabDefaultView'
  13.  
  14. import {
  15. AppRegistry,View,AlertIOS,StatusBar,} from 'react-native';
  16.  
  17.  
  18.  
  19. var Dimensions = require('Dimensions');
  20. var ScreenWidth = Dimensions.get('window').width;
  21.  
  22. class TabBottomView extends Component {
  23.  
  24. counter = 0;
  25. configureScene = route => {
  26. if (route.sceneConfig) return route.sceneConfig
  27.  
  28. return {
  29. ...Navigator.SceneConfigs.PushFromRight,gestures: {} // 禁用左滑返回手势
  30. }
  31. }
  32.  
  33. renderScene = (route,navigator) => {
  34. let Component = route.component
  35. return <Component navigator={navigator}{...route.passProps}/>
  36. }
  37.  
  38. inc = () => {
  39. ++this.counter;
  40. };
  41.  
  42. dec = () => {
  43. --this.counter;
  44. };
  45.  
  46. OnChangeText = v => {
  47. try {
  48. this.counter = parseInt(v);
  49. } catch (err) {
  50. }
  51.  
  52. };
  53.  
  54. OnClickText = (title) => {
  55. alert('title=' + title);
  56. }
  57.  
  58. render() {
  59. const initialPage = TabDefaultView;
  60. const initialPageName = 'TabBarView';
  61.  
  62. return (
  63. <View style={styles.container}>
  64. <StatusBar barStyle={'light-content'}/>
  65. <Navigator
  66. initialRoute={{name: initialPageName,component: initialPage}}
  67. configureScene={this.configureScene}
  68. renderScene={this.renderScene}/>
  69. </View>
  70.  
  71. );
  72. }
  73. }
  74.  
  75.  
  76. const styles = StyleSheet.create({
  77. container: {
  78. flex: 1,marginTop: 20
  79. },});
  80.  
  81. export default TabBottomView;

TabBottomView设计到的两个自定义View:
TabBarView.js

  1. /** * Sample React Native App * https://github.com/facebook/react-native * @flow TextInput自动提示输入 */
  2.  
  3. import React,{Component} from 'react';
  4. import {
  5. AppRegistry,TouchableOpacity,TextInput,View
  6. }
  7. from
  8. 'react-native';
  9.  
  10.  
  11. class TabBarView extends Component {
  12.  
  13. static propType = {
  14. goToPage : React.PropTypes.func,activeTab : React.PropTypes.number,tabs : React.PropTypes.array,tabNames : React.PropTypes.array,tabIconNames: React.PropTypes.array,selectedTabIconNames: React.PropTypes.array
  15. };
  16.  
  17. componentDidMount() {
  18. this.props.scrollValue.addListener(this.setAnimationValue);
  19. }
  20.  
  21. setAnimationValue({value}) {
  22. console.log(value);
  23. }
  24.  
  25. render() {
  26. return (
  27. <View style={styles.tabs}>
  28. {this.props.tabs.map((tab,i) => {
  29. let color = this.props.activeTab === i ? 'green' : 'gray';
  30. let icon = this.props.activeTab == i ? this.props.selectedTabIconNames[i] : this.props.tabIconNames[i];
  31. return (
  32. <TouchableOpacity
  33. key={i}
  34. activeOpacity={0.8}
  35. style={styles.tab}
  36. onPress={()=>this.props.goToPage(i)}>
  37. <View style={styles.tabItem}>
  38. <Image
  39. style={styles.icon}
  40. source={icon}/>
  41. <Text style={{color: color,fontSize: 12}}>
  42. {this.props.tabNames[i]}
  43. </Text>
  44. </View>
  45. </TouchableOpacity>
  46. )
  47. })}
  48. </View>
  49. );
  50. }
  51. }
  52.  
  53. const styles = StyleSheet.create({
  54. container: {
  55. flex: 1,backgroundColor: '#ffffff',marginTop: 20
  56. },tabs: {
  57. flexDirection: 'row',height: 49,borderTopColor: '#d9d9d9',borderTopWidth:2
  58. },tab: {
  59. flex: 1,justifyContent: 'center',alignItems: 'center',tabItem: {
  60. flexDirection: 'column',justifyContent: 'space-around'
  61. },icon: {
  62. width: 26,height: 26,marginBottom: 2
  63. }
  64. });
  65.  
  66. export default TabBarView;

TabDefaultView.js(默认界面)

  1. /** * Sample React Native App * https://github.com/facebook/react-native * @flow TextInput自动提示输入 */
  2.  
  3. import React,{Component} from 'react';
  4. import TabBarView from './TabBarView'
  5. import ScrollableTabView,ScrollableTabBar} from 'react-native-scrollable-tab-view';
  6. import HomeScreen from '../widght/HomeScreen';
  7. import MineScreen from '../widght/MineScreen';
  8.  
  9. import {
  10. AppRegistry,View
  11. }from 'react-native';
  12.  
  13. const tabTitles = ['首页','我的']
  14. //Tab图标
  15. const tabIcon = [
  16. require('../image/tabbar_homepage.png'),require('../image/tabbar_mine.png'),]
  17. const tabSelectedIcon = [
  18. require('../image/tabbar_homepage_selected.png'),require('../image/tabbar_mine_selected.png'),]
  19.  
  20. class TabDefaultView extends Component {
  21.  
  22. onChangeTabs = ({i}) => 'light-content';
  23.  
  24. render() {
  25. return (
  26. <ScrollableTabView
  27. renderTabBar={() =>
  28. <TabBarView
  29. tabNames={tabTitles}
  30. tabIconNames={tabIcon}
  31. selectedTabIconNames={tabSelectedIcon}/>
  32. }
  33. tabBarPosition='bottom'
  34. locked
  35. scrollWithoutAnimationz
  36. onChangeTab={this.onChangeTabs}>
  37.  
  38. <HomeScreen tabLabel="Home" navigator={this.props.navigator}/>
  39. <MineScreen tabLabel="Mine" navigator={this.props.navigator}/>
  40.  
  41. </ScrollableTabView>
  42. );
  43. }
  44. }
  45.  
  46. const styles = StyleSheet.create({
  47. container: {
  48. flex: 1,value:{
  49. paddingHorizontal:10,paddingVertical:8,width:100,marginLeft:120,}
  50. });
  51.  
  52. export default TabDefaultView;

最后在index.ios.js或index.android.js中导入组件。

  1. export default class RNDemo extends Component {
  2. render() {
  3. return (
  4. <TabBottomView/>
  5. );
  6. }
  7. }

附件:源码下载

猜你在找的React相关文章