React Native ScrollableTabView的自定义tabBar

        react-native-scrollable-tab-view是一个非常好用的TabBar组件,支持滑动,可以实现标签超过屏幕宽度的情况。但是有时会需要实现比如提示未读个数、定制样式这些需求,那么已有的功能就不能满足需求了。现在实现一个类似下图可标记未读及数量的自定义TabBar。原图找不到了,就类似网易首页顶部的tabbar,包括显示数字。

React Native ScrollableTabView的自定义tabBar_第1张图片
基本用法git地址:https://github.com/brentvatne/react-native-scrollable-tab-view,一个简单的例子:
  }>
		 
        	
        		界面1
        	          
         
         
         
         	
        		界面2
        	   
         
         
		 
         	
        		界面3
        	
         
         
		
        	
        		界面4
        	      
        
 

        属性renderTabBar就是tabbar组件。官方默认给了几个样式,如果实现自定义样式,就自己写一个组件然后赋值给它。

自定义TabBar样式
propTypes: {
    goToPage: PropTypes.func,
    activeTab: PropTypes.number,
    tabs: PropTypes.array,
    backgroundColor: PropTypes.string,
    activeTextColor: PropTypes.string,
    inactiveTextColor: PropTypes.string,
    scrollOffset: PropTypes.number,
    style: ViewPropTypes.style,
    tabStyle: ViewPropTypes.style,
    tabsContainerStyle: ViewPropTypes.style,
    textStyle: Text.propTypes.style,
    renderTab: PropTypes.func,
    underlineStyle: ViewPropTypes.style,
    onScroll: PropTypes.func,
  }

        ScrollableTabView的变量有上述这些,可以通过this.props.属性名来使用。比如:this.props.activeTab,是当前选择的tab,那么我们就可以利用这个属性来知道当前选择的是哪个tab。
        另外:this.props.containerWidth是tabbar的长度,this.props.tabs.length是tabbar的标签个数。通过这两个,可以实现底部那条选中哪个标签移动到哪个标签下的底部线的样式。
        还有,底部线移动的动画要怎么实现呢?在源码里看到这段注释:

  // Animated.add and Animated.divide do not currently support listeners so
  // we have to polyfill it here since a lot of code depends on being able
  // to add a listener to `scrollValue`. See https://github.com/facebook/react-native/pull/12620.

也就是说ScrollableTabView通过scrollValue来实现了一个组合动画,就直接使用this.props.scrollValue来使用已经实现的底部线的动画,可以通过动画的插值函数interpolate来实现我们想要的底部线的宽度,或实现移动时的伸缩效果,都可以通过这个来实现。

直接上自定义的tabbar
/**
 * @desc   ScrollableTabView的自定义tabBar组件,赋值给renderTabBar
 * 属性tabLabelNames,来记录需要的属性:showNum 是否显示数字,num 数量,showIcon 是否只展示小圆点。
 * @author MaRui
 */
import React from 'react';
import {
    StyleSheet,
    Text,
    View,
    TouchableOpacity,
    Animated,
} from 'react-native';

class CustomTabBar extends React.Component {

    constructor(props) {
        super(props);
    }

    render() {
        const containerWidth = this.props.containerWidth;
        const numberOfTabs = this.props.tabs.length;
        const tabUnderlineStyle = {
            position: 'absolute',
            width: containerWidth / numberOfTabs,
            height: 4,
            backgroundColor: 'navy',
            bottom: 0,
            justifyContent: 'center'
        };
        const translateX = this.props.scrollValue.interpolate({
            inputRange: [0, 1],
            outputRange: [0, containerWidth / numberOfTabs],
        });
        return 

            {this.props.tabLabelNames.map((tab, page) => {
                return  this.props.goToPage(page)} style={styles.tab}>

                    {tab.name}

                    
                        {(tab.showNum && tab.num !== 0) ? (tab.num > 99 ? '99+' : tab.num) : null}
                    

                ;
            })}

            
        ;
    }

}

const styles = StyleSheet.create({
    tab: {
        flexDirection: 'row',
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center'
    },
    tabs: {
        height: 45,
        flexDirection: 'row',
        justifyContent: 'space-around'
    },
    tabText: {
        fontSize: 14
    },
    tabNum: {
        borderRadius: 10,
        backgroundColor: '#E72E2E',
        height: 20,
        minWidth: 20,
        paddingHorizontal: 2,
        marginLeft: 2,
        alignItems: 'center',
        justifyContent: 'center'
    },
    tabNumText: {
        color: 'white',
        fontSize: 10,
        textAlign: 'center',
        lineHeight: 20,
        minWidth: 20
    },
    tabDot: {
        borderRadius: 8,
        marginLeft: 2,
        height: 8,
        width: 8,
        backgroundColor: '#E72E2E'
    },
    show: {
        display: 'flex'
    },
    hide: {
        display: 'none'
    }
});

export default MineTabBar;
例子
  }>
		 
         	
        		界面1
        	
         
         
         
         	
        		界面2
        	
         
         
		 
         	
        		界面3
        		      
         
         
		
        	
        		界面4
        	               
        
 

你可能感兴趣的:(React,Native)