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切換,還能實現底部的切換。
屬性及方法介紹
1, renderTabBar(Function:ReactComponent)
TabBar的樣式,係統提供了兩種默認的,分別是DefaultTabBar和ScrollableTabBar。當然,我們也可以自定義一個,我們會在下篇文章重點講解如何去自定義TabBar樣式。
注意:每個被包含的子視圖需要使用tabLabel屬性,表示對應Tab顯示的文字。
DefaultTabBar:Tab會平分在水平方向的空間。
ScrollableTabBar:Tab可以超過屏幕範圍,滾動可以顯示。
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欄沒有顏色)
render() {
return (
<ScrollableTabView
tabBarPosition='top'
renderTabBar={() => <DefaultTabBar/>}>
...
</ScrollableTabView>
);
}
3, onChangeTab(Function)
Tab切換之後會觸發此方法,包含一個參數(Object類型),這個對象有兩個參數:
i:被選中的Tab的下標(從0開始)
ref:被選中的Tab對象(基本用不到)
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來切換視圖。
render() {
return (
<ScrollableTabView
locked={false}
renderTabBar={() => <DefaultTabBar/>}>
...
</ScrollableTabView>
);
}
6, initialPage(Integer)
初始化時被選中的Tab下標,默認是0(即第一頁)。
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('../image/tabbar_homepage.png'),
require('../image/tabbar_mine.png'),
]
const tabSelectedIcon = [
require('../image/tabbar_homepage_selected.png'),
require('../image/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/>
);
}
}
附件:源碼下載
最後更新:2017-05-25 18:02:11
上一篇:
Bitbucket 版本控製入門指南
下一篇:
收錄對網站優化起到什麼作用?
Android自定義捕獲Application全局異常優化版
幾種常見的微服務架構方案——ZeroC IceGrid、Spring Cloud、基於消息隊列、Docker Swarm
Ubuntu啟動時不啟動Xwindow的方法
android View的一些學習記錄
“不倒翁”獨家二次開發完美運營版棋牌源碼搭建
adb常用命令,技巧
StartOS 5.0正式版發布,國人的操作係統
AliSQL 引領開源技術變革之路
你聽過無人駕駛,但你了解無人駕駛的算法嗎?
IBM WebSphere Application Server V7.0 Fix Pack 9於2010.03.25發布