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

效果图:

这里写图片描述

参考这篇文章(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 App
AppRegistry.registerComponent('AwesomeProject', () => App);
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页