React Native带你实现scrollable-tab-view(二)
来源:互联网 发布:sql注入绕过单引号 编辑:程序博客网 时间:2024/06/06 19:02
上一节React Native带你实现scrollable-tab-view(一)中我们最后实现了我们scrollable-tab-view的效果为:
代码为:
/** * @author YASIN * @version [React-Native Pactera V01, 2017/9/5] * @date 2017/9/5 * @description index */...... render() { return ( <View style={styles.container} > {/*渲染tabview*/} {this._renderTabView()} <ScrollView style={styles.scrollStyle} pagingEnabled={true} horizontal={true} > {['页面一', '页面二', '页面三'].map((item, index)=> { return ( <Text key={item + index} style={{ width: screenW, flex: 1, }} > {item} </Text> ); })} </ScrollView> </View> ); } /** * 渲染tabview * @private */ _renderTabView() { return ( <View style={styles.tabContainer} > {['页面一', '页面二', '页面三'].map((item, index)=> { return ( <TouchableOpacity key={item + index} style={styles.tabStyle} > <Text>{item}</Text> </TouchableOpacity> ); })} </View> ); }}......
作为一个第三方性的组件,这样写耦合性太高,不太容易复用,所以我们改改:
index.js:
export default class ScrollableTab extends Component { static propTypes = {} // 构造 constructor(props) { super(props); // 初始状态 this.state = {}; } render() { return ( <View style={styles.container} > {/*渲染tabview*/} {this._renderTabView()} {/*渲染主体内容*/} {this._renderScrollableContent()} </View> ); } /** * 渲染tabview * @private */ _renderTabView() { let tabParams = { tabs: this._children().map((child)=>child.props.tabLabel), }; return ( <DefaultTabBar {...tabParams} /> ); } /** * 渲染主体内容 * @private */ _renderScrollableContent() { return ( <Animated.ScrollView style={styles.scrollStyle} pagingEnabled={true} horizontal={true} > {this.props.children} </Animated.ScrollView> ); } /** * 获取子控件数组集合 * @param children * @returns {*} * @private */ _children(children = this.props.children) { return React.Children.map(children, (child)=>child); }}
然后把之前的渲染_renderTabView的代码变成了一个单独的组件DefaultTabBar.js,然后传入tabs即为我们需要的tab内容:
DefaultTabBar.js:
/** * @author YASIN * @version [React-Native Pactera V01, 2017/9/5] * @date 17/2/23 * @description DefaultTabBar */import React, { Component, PropTypes,} from 'react';import { View, Text, StyleSheet, TouchableOpacity, Dimensions,} from 'react-native';const screenW = Dimensions.get('window').width;const screenH = Dimensions.get('window').height;export default class DefaultTabBar extends Component { static propTypes = { tabs: PropTypes.array, } // 构造 constructor(props) { super(props); // 初始状态 this.state = {}; } render() { return ( <View style={styles.container}> {this.props.tabs.map((name, page) => { return this._renderTab(name, page); })} </View> ); } /** * 渲染tab * @param name 名字 * @param page 下标 * @private */ _renderTab(name, page) { return ( <TouchableOpacity key={name + page} style={styles.tabStyle} > <Text>{name}</Text> </TouchableOpacity> ); }}const styles = StyleSheet.create({ container: { width: screenW, flexDirection: 'row', alignItems: 'center', height: 50, }, tabStyle: { flex: 1, alignItems: 'center', justifyContent: 'center', }});
然后我们用的时候只需要渲染自己的内容模块就可以了:
export default class ScrollTabDemo extends Component { render() { return ( <View style={styles.container}> <ScrollableTab> {['页面一', '页面二', '页面三'].map((item, index)=> { return ( <Text tabLabel={item} key={item + index} style={{ width: screenW, flex: 1, }} > {item} </Text> ); })} </ScrollableTab> {/*<App/>*/} </View> ); }}
哈哈~~ 是不是很熟悉呢? scrollable-tab-view第三方库就是这么用的,没有啥高大上的东西,只是把公共部分提取出来了,这也就是自定义组件存在的目的。
然后运行代码,跟我们一开始一样的效果~~~
接下来我们得知道我们每次滑动scrollview后我们停留在哪个页面,主要就是用到scrollview的onMomentumScrollBegin跟onMomentumScrollEnd属性,这两个是干嘛的呢?就是当滑动开始跟滑动结束时候的回调。
怎么拿到我们的当前页面呢?
onMomentumScrollBegin跟onMomentumScrollEnd会返回event,event里面包含scrollview在y轴的偏移量,Math.round(y轴的偏移量/控件的宽度)即为当前页面。
有了思路我们就开动了哈~
获取控件的宽度应该是没问题哈,我们定义一个叫containerWidth的变量,然后默认宽度为屏幕宽:
render() { return ( <View style={styles.container} onLayout={this._onLayout} > {/*渲染tabview*/} {this._renderTabView()} {/*渲染主体内容*/} {this._renderScrollableContent()} </View> ); }
/** * 获取控件宽度 * @param e * @private */ _onLayout = (e)=> { let {width}=e.nativeEvent.layout; if (this.state.containerWidth !== width) { this.setState({ containerWidth: width, }); } }
好了,我们已经获取到我们控件的宽度了,于是我们开始处理_onMomentumScrollBeginAndEnd方法:
/** * 渲染主体内容 * @private */ _renderScrollableContent() { return ( <Animated.ScrollView style={{width: this.state.containerWidth}} pagingEnabled={true} horizontal={true} onMomentumScrollBegin={this._onMomentumScrollBeginAndEnd} onMomentumScrollEnd={this._onMomentumScrollBeginAndEnd} > {this.props.children} </Animated.ScrollView> ); }
/** * scrollview开始跟结束滑动回调 * @param e * @private */ _onMomentumScrollBeginAndEnd = (e) => { let offsetX = e.nativeEvent.contentOffset.x; let page = Math.round(offsetX / this.state.containerWidth); if (this.state.currentPage !== page) { console.log('当前页面-->'+page); this.setState({ currentPage: page, }); } }
我们运行代码:
既然我们拿到了当前当前页面页码,然后我们试着把对应的tab置为红色,没选中的为绿色:
于是我们把页码传入DefaultTabView:
/** * 渲染tabview * @private */ _renderTabView() { let tabParams = { tabs: this._children().map((child)=>child.props.tabLabel), activeTab: this.state.currentPage, }; return ( <DefaultTabBar {...tabParams} style={[{width: this.state.containerWidth}]} /> ); }
然后在DefaultTabView中,如果当前tab的下标为activeTab就显示红色:
DefaultTabView.js:
/** * @author YASIN * @version [React-Native Pactera V01, 2017/9/5] * @date 17/2/23 * @description DefaultTabBar */import React, { Component, PropTypes,} from 'react';import { View, Text, StyleSheet, TouchableOpacity, Dimensions,} from 'react-native';const screenW = Dimensions.get('window').width;const screenH = Dimensions.get('window').height;export default class DefaultTabBar extends Component { static propTypes = { tabs: PropTypes.array, activeTab: PropTypes.number,//当前选中的tab style: View.propTypes.style, } // 构造 constructor(props) { super(props); // 初始状态 this.state = {}; } render() { return ( <View style={[styles.container, this.props.style]}> {this.props.tabs.map((name, page) => { const isTabActive = this.props.activeTab === page; return this._renderTab(name, page, isTabActive); })} </View> ); } /** * 渲染tab * @param name 名字 * @param page 下标 * @param isTabActive 是否是选中的tab * @private */ _renderTab(name, page, isTabActive) { let tabTextStyle = null; //如果被选中的style if (isTabActive) { tabTextStyle = { color:'green' }; } else { tabTextStyle = { color:'red' }; } return ( <TouchableOpacity key={name + page} style={[styles.tabStyle]} > <Text style={[tabTextStyle]}>{name}</Text> </TouchableOpacity> ); }}const styles = StyleSheet.create({ container: { width: screenW, flexDirection: 'row', alignItems: 'center', height: 50, }, tabStyle: { flex: 1, alignItems: 'center', justifyContent: 'center', }});
然后运行代码:
可以看到,我们简单的就可以玩起来了,好啦~ 这一节先到这里了,下一节我们来完成点击tab切换到指定页面,然后把tabview的指示线显示出来。
欢迎入群,欢迎交流,大牛勿喷~~
- React Native带你实现scrollable-tab-view(二)
- React Native带你实现scrollable-tab-view(一)
- React Native带你实现scrollable-tab-view(三)
- React Native带你实现scrollable-tab-view(四)
- React Native带你实现scrollable-tab-view(五)
- React Native带你实现scrollable-tab-view(完结)
- React:react-native-scrollable-tab-view
- ReactNative组件-react-native-scrollable-tab-view
- react-native-scrollable-tab-view 使用总结
- react-native-scrollable-tab-view详解
- 选项卡react-native-scrollable-tab-view
- [React Native]react-native-scrollable-tab-view(入门篇)
- [React Native]react-native-scrollable-tab-view(进阶篇)
- React Native之react-native-scrollable-tab-view详解
- [React Native]react-native-scrollable-tab-view(入门篇)
- [React Native]react-native-scrollable-tab-view(入门篇)
- 选项卡react-native-scrollable-tab-view(入门篇)
- 选项卡react-native-scrollable-tab-view(进阶篇)
- 友盟第三方分享步骤
- Java Serializable(序列化)的理解和总结
- eclipse下打包java项目为jar文件
- 堆的基本代码
- Linux界的老古董
- React Native带你实现scrollable-tab-view(二)
- Linux Shell编程入门
- 题目22-素数求和问题
- 【15】Bootstrap — 输入框组
- ThreadPoolExecutor + Callable + Future Example
- 面试题系列(一)
- (转)ICO泡沫:8万本金赚套房子和宝马 几分钟十几万没了
- 【转载】UCOS临界代码问题以及解决办法
- HDOJ_1002_A + B Problem II