react-native-scrollable-tab-view詳解

原文連接react

在React Native開發中,官方爲咱們提供的Tab控制器有兩種:TabBarIOS和ViewPagerAndroid。TabBarIOS,僅適用於IOS平臺
ViewPagerAndroid,僅適用於Android平臺(嚴格來說並不算,由於咱們還須要本身實現Tab)。在項目開發中,咱們優先選擇一些開源兼容性比較好的第三方庫,例如,react-navigation,以及本文即將說到的react-native-scrollable-tab-view(官方地址)。react-native-scrollable-tab-view不只能夠實現頂部的Tab切換,還能實現底部的切換。
這裏寫圖片描述這裏寫圖片描述android

咱們再來看一下官方的Demo。
這裏寫圖片描述ios

屬性及方法介紹

1, renderTabBar(Function:ReactComponent)git

TabBar的樣式,系統提供了兩種默認的,分別是DefaultTabBar和ScrollableTabBar。固然,咱們也能夠自定義一個,咱們會在下篇文章重點講解如何去自定義TabBar樣式。
注意:每一個被包含的子視圖須要使用tabLabel屬性,表示對應Tab顯示的文字。
DefaultTabBar:Tab會平分在水平方向的空間。
ScrollableTabBar:Tab能夠超過屏幕範圍,滾動能夠顯示。github

render() {
  return (    <ScrollableTabView
      renderTabBar={() => <DefaultTabBar/>}>      <Text tabLabel='Tab1'/>
      <Text tabLabel='Tab2'/>
      <Text tabLabel='Tab3'/>
      <Text tabLabel='Tab4'/>
      <Text tabLabel='Tab5'/>
      <Text tabLabel='Tab6'/>
    </ScrollableTabView>
  );
}

2,tabBarPosition(String,默認值'top')
top:位於屏幕頂部
bottom:位於屏幕底部
overlayTop:位於屏幕頂部,懸浮在內容視圖之上(看顏色區分:視圖有顏色,Tab欄沒有顏色)
overlayBottom:位於屏幕底部,懸浮在內容視圖之上(看顏色區分:視圖有顏色,Tab欄沒有顏色)npm

render() {  return (    <ScrollableTabView
      tabBarPosition='top'
      renderTabBar={() => <DefaultTabBar/>}>
      ...    </ScrollableTabView>
  );
}

3, onChangeTab(Function)
Tab切換以後會觸發此方法,包含一個參數(Object類型),這個對象有兩個參數:
i:被選中的Tab的下標(從0開始)
ref:被選中的Tab對象(基本用不到)react-native

render() {  return (    <ScrollableTabView
      renderTabBar={() => <DefaultTabBar/>}
      onChangeTab={(obj) => {
          console.log('index:' + obj.i);
        }
      }>
      ...    </ScrollableTabView>
  );
}

4,onScroll(Function)
視圖正在滑動的時候觸發此方法,包含一個Float類型的數字,範圍是[0, tab的數量-1]數組

render() {  return (    <ScrollableTabView
      renderTabBar={() => <DefaultTabBar/>}
      onScroll={(postion) => {  
          // float類型 [0, tab數量-1]  
          console.log('scroll position:' + postion);
        }
      }>
      ...    </ScrollableTabView>
  );
}

5, locked(Bool,默認爲false)
表示手指是否能拖動視圖,默認爲false(表示能夠拖動)。設爲true的話,咱們只能「點擊」Tab來切換視圖。less

render() {  return (    <ScrollableTabView
      locked={false}
      renderTabBar={() => <DefaultTabBar/>}>
      ...    </ScrollableTabView>
  );
}

6, initialPage(Integer)
初始化時被選中的Tab下標,默認是0(即第一頁)。ide

render() {  return (    <ScrollableTabView
      initialPage={1}
      renderTabBar={() => <DefaultTabBar/>}>
      ...    </ScrollableTabView>
  );
}

7,page(Integer)
設置選中指定的Tab。

8,children(ReactComponents)
表示全部子視圖的數組,好比下面的代碼,children則是一個長度爲6的數組,元素類型爲Text。

render() {
  return (    <ScrollableTabView
      renderTabBar={() => <DefaultTabBar/>}>      <Text tabLabel='Tab1'/>
      <Text tabLabel='Tab2'/>
      <Text tabLabel='Tab3'/>
      <Text tabLabel='Tab4'/>
      <Text tabLabel='Tab5'/>
      <Text tabLabel='Tab6'/>
    </ScrollableTabView>
  );
}

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(即:有動畫效果)。

render() {  return (    <ScrollableTabView
      scrollWithoutAnimation={true}
      renderTabBar={() => <DefaultTabBar/>}>
      ...    </ScrollableTabView>
  );
}

頂部導航示例

頂部導航的代碼是比較簡單的。例如,咱們實現上圖的新聞Tab導航的效果。
這裏寫圖片描述

相關代碼:

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

 import React, { Component } from 'react'; import ScrollableTabView, {DefaultTabBar,ScrollableTabBar} from 'react-native-scrollable-tab-view'; import {
   AppRegistry,
   StyleSheet,
   Text,
   Image,
   View
 } from 'react-native';var Dimensions = require('Dimensions');var ScreenWidth = Dimensions.get('window').width;class TabTopView extends Component {
    render() {        return (            <ScrollableTabView
                style={styles.container}
                renderTabBar={() => <DefaultTabBar />}
                tabBarUnderlineStyle={styles.lineStyle}
                tabBarActiveTextColor='#FF0000'>                <Text style={styles.textStyle} tabLabel='娛樂'>娛樂</Text>
                <Text style={styles.textStyle} tabLabel='科技'>科技</Text>
                <Text style={styles.textStyle} tabLabel='軍事'>軍事</Text>
                <Text style={styles.textStyle} tabLabel='體育'>體育</Text>
            </ScrollableTabView>
        );
    }
    } const styles = StyleSheet.create({     container: {         flex: 1,         marginTop: 20
     },     lineStyle: {         width:ScreenWidth/4,         height: 2,         backgroundColor: '#FF0000',
     },     textStyle: {         flex: 1,         fontSize:20,         marginTop:20,         textAlign:'center',
     },

 });export default TabTopView;

而後在index.ios.js或index.android.js中導入組件。

export default class RNDemo extends Component {
    render() {        return (
            <TabBottomView/>
        );
    }
}

底部Tab切換示例

這裏寫圖片描述

須要注意的是項目中用到了Navigator這個組件,在最新的版本中,系統標識Navigator已通過時被拋棄,因此咱們須要使用命令先按照相關的庫:

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

這裏寫圖片描述

而後在使用的界面中導入Navigator。

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

好了其餘的再也不說明,直接上代碼:
TabBottomView.js

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */import React, {Component} from 'react';import {
    Navigator,
} from 'react-native-deprecated-custom-components';import TabBarView from './TabBarView'import TabDefaultView from './TabDefaultView'import {
    AppRegistry,
    StyleSheet,
    Text,
    Image,
    View,
    AlertIOS,
    StatusBar,
} from 'react-native';var Dimensions = require('Dimensions');var ScreenWidth = Dimensions.get('window').width;class TabBottomView extends Component {

    counter = 0;
    configureScene = route => {        if (route.sceneConfig) return route.sceneConfig        return {
            ...Navigator.SceneConfigs.PushFromRight,
            gestures: {}    // 禁用左滑返回手勢
        }
    }

    renderScene = (route, navigator) => {
        let Component = route.component        return <Component navigator={navigator}{...route.passProps}/>
    }

    inc = () => {
        ++this.counter;
    };

    dec = () => {
        --this.counter;
    };

    OnChangeText = v => {        try {            this.counter = parseInt(v);
        } catch (err) {
        }

    };

    OnClickText = (title) => {
        alert('title=' + title);
    }

    render() {        const initialPage = TabDefaultView;        const initialPageName = 'TabBarView';        return (
            <View style={styles.container}>
                <StatusBar barStyle={'light-content'}/>
                <Navigator
                    initialRoute={{name: initialPageName, component: initialPage}}
                    configureScene={this.configureScene}
                    renderScene={this.renderScene}/>
            </View>

        );
    }
}const styles = StyleSheet.create({
    container: {
        flex: 1,
        marginTop: 20
    },


});export default TabBottomView;

TabBottomView設計到的兩個自定義View:
TabBarView.js

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow TextInput自動提示輸入
 */import React, {Component} from 'react';import {
    AppRegistry,
    StyleSheet,
    Text,
    TouchableOpacity,
    Image,
    TextInput,
    View
}
from'react-native';class TabBarView extends Component {

    static propType = {
        goToPage    : React.PropTypes.func,
        activeTab   : React.PropTypes.number,
        tabs        : React.PropTypes.array,

        tabNames    : React.PropTypes.array,
        tabIconNames: React.PropTypes.array,
        selectedTabIconNames: React.PropTypes.array
    };

    componentDidMount() {        this.props.scrollValue.addListener(this.setAnimationValue);
    }

    setAnimationValue({value}) {
        console.log(value);
    }

    render() {        return (
            <View style={styles.tabs}>
                {this.props.tabs.map((tab, i) => {
                    let color = this.props.activeTab === i ? 'green' : 'gray';
                    let icon = this.props.activeTab == i ? this.props.selectedTabIconNames[i] : this.props.tabIconNames[i];                    return (
                        <TouchableOpacity
                            key={i}
                            activeOpacity={0.8}
                            style={styles.tab}
                            onPress={()=>this.props.goToPage(i)}>
                            <View style={styles.tabItem}>
                                <Image
                                    style={styles.icon}
                                    source={icon}/>
                                <Text style={{color: color, fontSize: 12}}>
                                    {this.props.tabNames[i]}
                                </Text>
                            </View>
                        </TouchableOpacity>
                    )
                })}
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#ffffff',
        marginTop: 20
    },
    tabs: {
        flexDirection: 'row',
        height: 49,
        borderTopColor: '#d9d9d9',
        borderTopWidth:2
    },
    tab: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
    },
    tabItem: {
        flexDirection: 'column',
        alignItems: 'center',
        justifyContent: 'space-around'
    },
    icon: {
        width: 26,
        height: 26,
        marginBottom: 2
    }
});

export default TabBarView;

TabDefaultView.js(默認界面)

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow TextInput自動提示輸入
 */import React, {Component} from 'react';import TabBarView from './TabBarView'import ScrollableTabView, {DefaultTabBar, ScrollableTabBar} from 'react-native-scrollable-tab-view';import HomeScreen from '../widght/HomeScreen';import MineScreen from '../widght/MineScreen';import {
    AppRegistry,
    StyleSheet,
    Text,
    TouchableOpacity,
    Image,
    TextInput,
    StatusBar,
    View
}from 'react-native';const tabTitles = ['首頁', '個人']//Tab圖標const tabIcon = [
    require('../p_w_picpath/tabbar_homepage.png'),
    require('../p_w_picpath/tabbar_mine.png'),
]const tabSelectedIcon = [
    require('../p_w_picpath/tabbar_homepage_selected.png'),
    require('../p_w_picpath/tabbar_mine_selected.png'),
]class TabDefaultView extends Component {

    onChangeTabs = ({i}) => 'light-content';

    render() {        return (
            <ScrollableTabView
                renderTabBar={() =>
                    <TabBarView
                        tabNames={tabTitles}
                        tabIconNames={tabIcon}
                        selectedTabIconNames={tabSelectedIcon}/>
                }
                tabBarPosition='bottom'
                locked
                scrollWithoutAnimationz
                onChangeTab={this.onChangeTabs}>

                <HomeScreen tabLabel="Home" navigator={this.props.navigator}/>
                <MineScreen tabLabel="Mine" navigator={this.props.navigator}/>

            </ScrollableTabView>
        );
    }
}const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#ffffff',
        marginTop: 20
    },
    value:{
        paddingHorizontal:10,
        paddingVertical:8,
        width:100,
        marginLeft:120,
    }
});export default TabDefaultView;

最後在index.ios.js或index.android.js中導入組件。

export default class RNDemo extends Component {
    render() {        return (
            <TabBottomView/>
        );
    }
}

附件:×××

相關文章
相關標籤/搜索