React Native利用ScrollableTabView实现Tab+ViewPager效果

来源:互联网 发布:知乎 中美军演 编辑:程序博客网 时间:2024/06/05 10:58

效果图:

这里写图片描述

参考这篇文章(http://www.jianshu.com/p/b7788c3d106e)实现了简单的Tab+ViewPager效果。然后将里面的Text改为FlatList来显示更多数据。接着我想点击里面的数据跳转到另一个界面。但是没有找到FlatList 的点击回调函数,找了找资料才发现,不像Android里的控件有onClick方法,React Native里需要在要实现点击相应的控件外面加上”Touchable”开头的一系列组件来实现的。(http://reactnative.cn/docs/0.47/handling-touches.html#content)

例如:

class MyButton extends Component {  _onPressButton() {    console.log("You tapped the button!");  }  render() {    return (      <TouchableHighlight onPress={this._onPressButton}>        <Text>Button</Text>      </TouchableHighlight>    );  }}

在FlatList里的Text外加入Touchable标签后(只需关注Touchable里的)

<FlatList          data={[            {key: 'Devin'},            {key: 'Jackson'},            {key: 'James'},            {key: 'Joel'},            {key: 'John'},            {key: 'Jillian'},            {key: 'Jimmy'},            {key: 'Julie'},          ]}          renderItem={({item}) =>           <TouchableNativeFeedback              onPress = {this.onPress}>               <Text style={styles.item}>{item.key}</Text>          </TouchableNativeFeedback>          }        />        。。。        onPress(){        。。。        }

这样可以相应点击事件了,但是还需要知道点击的是哪个item的Text,需要把item传递给onPress(),我以为只需修改两行代码

    。。。    onPress = {this.onPress(item)}>    。。。    onPress(item){    。。。    }

就可以了,实际上是不行的,React Native里传递参数是这样写的

    。。。    onPress = {this.onPress.bind(this,item)}>    。。。    onPress(item){    。。。    }

然后把FlatList封装一下,命名为MyFlatList

class MyFlatList extends Component{  render(){    var dataSource = this.props.dataSource;    var renderItem = this.props.renderItem;    return(      <FlatList       data = {dataSource.list}      renderItem = {renderItem}      />    )  }}。。。//使用方法render() {    var dataSource1 = {      tab:'Tab1',      list:[      {key: 'item0',index:'0'},      {key: 'item1',index:'1'},      {key: 'item2',index:'2'},      {key: 'item3',index:'3'},      ]    } return (          。。。                    <ScrollableTabView          style={styles.pagerView}          renderTabBar={() => <DefaultTabBar />}          tabBarUnderlineStyle={styles.lineStyle}          tabBarActiveTextColor='#FF0000'>                    <MyFlatList tabLabel = {dataSource1.tab}//ScrollableTabView子视图需要使用tabLabel属性,表示对应Tab显示的文字          dataSource = {dataSource1}          renderItem = {({item}) =>              <TouchableNativeFeedback                  onPress = {this.onPress.bind(this,item)}>                  <Text style = {styles.textMainStyle}>{item.key}</Text>              </TouchableNativeFeedback>        }        />

接着就要处理跳转事件了,是利用Navigation实现的(http://reactnative.cn/docs/0.47/navigation.html#content)
需要注意的是注册时要换成StackNavigator的名称,例如:

    const App = StackNavigator({      Main: { screen: MainScreen },      Details: { screen: DetailsScreen },    });    。。。    //AwesomeProject为init时的工程名字    AppRegistry.registerComponent('AwesomeProject', () => App);

传递的参数是uri,跳转到的新界面是用WebView来进行显示

    <WebView            source={{uri:params.uri,method: 'GET'}}          javaScriptEnabled={true}          startInLoadingState={true}          domStorageEnabled={true}          scalesPageToFit={false}       />  

完整代码:

import React, { Component } from 'react';import ScrollableTabView, {DefaultTabBar,ScrollableTabBar} from 'react-native-scrollable-tab-view';import { AppRegistry, FlatList, StyleSheet, Text, View, TouchableNativeFeedback, WebView} from 'react-native';import { StackNavigator } from 'react-navigation';var Dimensions = require('Dimensions');var ScreenWidth = Dimensions.get('window').width;class DetailsScreen extends Component{  render(){    const {params} = this.props.navigation.state;    return(      <View style = {styles.container}>      <WebView            source={{uri:params.uri,method: 'GET'}}          javaScriptEnabled={true}          startInLoadingState={true}          domStorageEnabled={true}          scalesPageToFit={false}        />        </View>      )  }}class MyFlatList extends Component{  render(){    var dataSource = this.props.dataSource;    var renderItem = this.props.renderItem;    return(      <FlatList       data = {dataSource.list}      renderItem = {renderItem}      />    )  }}class MainScreen extends Component {  static navigationOptions = { header: null };  render() {    var dataSource1 = {      tab:'Tab1',      list:[      {key: 'item0',index:'0'},      {key: 'item1',index:'1'},      {key: 'item2',index:'2'},      {key: 'item3',index:'3'},      ]    }     var dataSource2 = {      tab:'Tab2',      list:[      {key: 'item4',index:'4'},      {key: 'item5',index:'5'},      {key: 'item6',index:'6'},      {key: 'item7',index:'7'},      ]    }     var dataSource3 = {      tab:'Tab3',      list:[      {key: 'item8',index:'8'},      {key: 'item9',index:'9'},      {key: 'item10',index:'10'},      {key: 'item11',index:'11'},      ]    }         // const {navigate} = this.props.navigation;        return (          <View style = {styles.container}>          <View style = {styles.headerView}><Text style = {styles.textHeaderStyle}>Header</Text>          </View>          <ScrollableTabView          style={styles.pagerView}          renderTabBar={() => <DefaultTabBar />}          tabBarUnderlineStyle={styles.lineStyle}          tabBarActiveTextColor='#FF0000'>                    <MyFlatList tabLabel = {dataSource1.tab}          dataSource = {dataSource1}          renderItem = {({item}) =>          <TouchableNativeFeedback          onPress = {this.onPress.bind(this,item)}>          <Text style = {styles.textMainStyle}>{item.key}</Text>          </TouchableNativeFeedback>        }        />        <MyFlatList tabLabel = {dataSource2.tab}          dataSource = {dataSource2}          renderItem = {({item}) =>          <TouchableNativeFeedback          onPress = {this.onPress.bind(this,item)}>          <Text style = {styles.textMainStyle}>{item.key}</Text>          </TouchableNativeFeedback>        }        />        <MyFlatList tabLabel = {dataSource3.tab}          dataSource = {dataSource3}          renderItem = {({item}) =>          <TouchableNativeFeedback          onPress = {this.onPress.bind(this,item)}>          <Text style = {styles.textMainStyle}>{item.key}</Text>          </TouchableNativeFeedback>        }        />        </ScrollableTabView>        </View>         );      }      onPress(item){        var uri = '';        const {navigate} = this.props.navigation;        switch(item.index){          case '0':          uri = 'http://www.baidu.com';          break;            case '1':          uri = 'http://www.baidu.com';          break;          case '2':          uri = 'http://www.baidu.com';          break;          case '3':          uri = 'http://www.baidu.com';          break;          case '4':          uri = 'http://www.baidu.com';          break;          case '5':          uri = 'http://www.baidu.com';          break;          case '6':          uri = 'http://www.baidu.com';          break;          case '7':          uri = 'http://www.baidu.com';          break;          case '8':          uri = 'http://www.baidu.com';          break;          case '9':          uri = 'http://www.baidu.com';          break;          case '10':          uri = 'http://www.baidu.com';          break;          case '11':          uri = 'http://www.baidu.com';          break;          default:          uri = 'http://www.baidu.com';          break;        }        navigate('Details',{uri:uri});      }    }    const App = StackNavigator({      Main: { screen: MainScreen },      Details: { screen: DetailsScreen },    });    const styles = StyleSheet.create({      container: {       flex: 1,       flexDirection: 'column',       backgroundColor: 'white'     },     headerView:{      flex: 1,      backgroundColor: 'skyblue',        justifyContent : 'center',      alignItems: 'center'    },    pagerView:{      flex: 6,      backgroundColor: 'white'    },    lineStyle: {     // width:ScreenWidth/3,     height: 2,     backgroundColor: '#FF0000',   },   textMainStyle: {     flex: 1,     fontSize:40,     marginTop:10,     textAlign:'center',     color: 'black'   },   textHeaderStyle:{    fontSize: 40,    color: 'white',  }})// skip this line if using Create React Native AppAppRegistry.registerComponent('AwesomeProject', () => App);