繁体   English   中英

将本机平面列表反应到选项卡屏幕

[英]React native flatlist to tab screens

我有一个列出客户项目的清单。 当我按每个项目时,它将导航到主屏幕选项卡,其中包含3个选项卡屏幕:

  • 客户资料
  • 客户的当前地址
  • 客户的帐单地址。

这三个屏幕从不同的API获取数据,但取决于客户ID。 我如何将平面列表键传递给这些屏幕,以便显示来自任何API的数据?

这是我目前的代码:

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View
} from 'react-native';
import TabNavigator from 'react-native-tab-navigator';
import Icon from 'react-native-vector-icons/FontAwesome';
import {Dimensions} from 'react-native';

const deviceW = Dimensions.get('window').width

const basePx = 768

function px2dp(px) {
  return px *  deviceW / basePx
}

class Info extends Component {
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>
        Customer info:_____
        </Text>
      </View>
    )
  }
}

class currentadd extends Component {
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>
          current address is:_____
        </Text>
      </View>
    )
  }
}

class billingadd extends Component {
    render() {
      return (
        <View style={styles.container}>
          <Text style={styles.welcome}>
            Billing address is:_____
          </Text>
        </View>
      )
    }
  }


export default class CustomerDetail extends Component {

  static navigationOptions = ({ navigation }) => {
    return {
      title: `${navigation.state.params.custid}`,
    }
  };


  state= {
    selectedTab: 'info'
  }; 

  render() {
    return (
      <TabNavigator style={styles.container}>
        <TabNavigator.Item
          selected={this.state.selectedTab === 'info'}
          title="Customer General Info"
          selectedTitleStyle={{color: "#3496f0"}}
          renderIcon={() => <Icon name="user" size={px2dp(22)} color="#666"/>}
          renderSelectedIcon={() => <Icon name="user" size={px2dp(22)} color="#3496f0"/>}
          onPress={() => this.setState({selectedTab: 'info'})}>
          <Info />
        </TabNavigator.Item>
        <TabNavigator.Item
          selected={this.state.selectedTab === 'currentadd'}
          title="current address"
          selectedTitleStyle={{color: "#3496f0"}}
          renderIcon={() => <Icon name="usd" size={px2dp(22)} color="#666"/>}
          renderSelectedIcon={() => <Icon name="home" size={px2dp(22)} color="#3496f0"/>}
          onPress={() => this.setState({selectedTab: 'currentadd'})}>
          <currentadd/>
        </TabNavigator.Item>
        <TabNavigator.Item
          selected={this.state.selectedTab === 'billingadd'}
          title="billing address"
          selectedTitleStyle={{color: "#3496f0"}}
          renderIcon={() => <Icon name="usd" size={px2dp(22)} color="#666"/>}
          renderSelectedIcon={() => <Icon name="phone" size={px2dp(22)} color="#3496f0"/>}
          onPress={() => this.setState({selectedTab: 'billingadd'})}>
          <billingadd/>
        </TabNavigator.Item>
      </TabNavigator>
    );
  }
}
...stylesheet here

先感谢您。

我认为您可以应用以下示例,在您的应用程序中,主要思想是将对象(ID)的标识符发送给其他子对象,因此,您可以在执行操作时捕获此ID。您的组件,例如:

class Decks extends Component { 
   render () {

        const { decks } = this.props;

        return (
            <View>
                {Object.keys(decks).map((key) => {
                    return (
                        <View key={key} style={styles.deck}>
                            <TouchableOpacity onPress={() => this.props.navigation.navigate('DeckProfile', { 
                                title: decks[key].title
                                })}>
                            </TouchableOpacity>
                        </View>
                    )
                })}
          </View>
        )
    }
}

因此,在“导航”功能中发送的组件将在此时执行按下操作,同时还将发送主要组件的ID(在本例中为“标题”)。 必须根据之前使用的参数在MainNavigator中对此进行定义,在本例中为“ title”:

const MainNavigator = StackNavigator({

  DeckProfile: {
    screen: DeckProfile,
    navigationOptions: ({navigation}) => ({
      title: navigation.state.params.title,
      headerTintColor: white,
      headerStyle: {
        backgroundColor: lightPurp,
      }
    })
  }

:),Okey,因此您在'CustomerDetail'屏幕中具有'custid',并且选项卡屏幕需要获取此信息(custid),为了传递此信息,可以使用this.props.navigation.state.params.title (在您的情况下,可能是“ custid”而不是“ title”),流程如下所示:

CustomerList.js组件:

class CustomerList extends Component { 
   render () {

        const { customers } = this.props;

        return (
            <View>
                {Object.keys(customers).map((key) => {
                    return (
                        <View key={key} style={styles.customer}>
                            <TouchableOpacity onPress={() => this.props.navigation.navigate('CustomerDetail', { 
                                custid: customers[key].custid
                                })}>
                            </TouchableOpacity>
                        </View>
                    )
                })}
          </View>
        )
    }
}

App.js组件:

const MainNavigator = StackNavigator({

  CustomerDetail: {
    screen: CustomerDetail,
    navigationOptions: ({navigation}) => ({
      custid: navigation.state.params.custid,
      headerTintColor: white,
      headerStyle: {
        backgroundColor: lightPurp,
      }
    })
  }

CustomerDetail.js组件:

CustomerDetail类扩展了组件{

render () {
    const { customers } = this.props;
    let custid = this.props.navigation.state.params.custid;

    return(
        <TabNavigator style={styles.container}>
           <TabNavigator.Item
            title={customers[custid].name}
           </TabNavigator.Item>
        </TabNavigator>
    )
}

App.js

import React, { Component } from 'react';
import { StyleSheet } from 'react-native';
import { StackNavigator } from 'react-navigation';

import Login from './src/components/Login';
import Home from './src/components/Home';
import Dashboard from './src/components/Dashboard';
import Customer from './src/components/Customer';
import CustomerDetail from './src/components/CustomerDetail';

const MyApp = StackNavigator(

    {
      Login: {
        screen: Login,
        navigationOptions: {
          header: null
        },
      },
      Home: {
        screen: Home,
        navigationOptions: {
          header: null
        },
      },
      Dashboard: {
        screen: Dashboard,
        navigationOptions: {
          title: 'Dashboard'
        },
      },
      Customer: {
        screen: Customer,
        navigationOptions: {
          title:'List of customers'
        }
      },
      CustomerDetail: {
        screen: CustomerDetail,
        navigationOptions: {
          title:'Customer Detail'
        }
      }
    });

export default class App extends React.Component {
  render() {
    return (
      <MyApp />
    );
  }
}

Customer.js

import React, { Component } from 'react';
import { View, Text, FlatList, ActivityIndicator, Alert, TouchableOpacity} from "react-native";
import { List, ListItem, Icon } from "react-native-elements";
import { Navigator } from 'react-navigation';
import SearchBar from './SearchBar';


export default class Customer extends Component {

  state = {
    loading: false,
    data: []
  }

  componentWillMount() {
    this.searchCust('M000');
  }

  onPressSearch = term => {
    if(term == '')
      {
        Alert.alert("Enter to search");
      }
    else
    {
      this.searchCust(term);
    }
  }

  searchCust = term => {
    this.setState({ loading: true });

      const url = `http://xxx.xxx.xxx.xxx/app/customerlist.php?term=${term}`;
        fetch(url)
          .then(res => res.json())
          .then(res => {
            this.setState({
              data: res.results,
              error: res.error || null,
              loading: false,
            });
          })
        .catch(error => {
          this.setState({ error });
      });
  }

  goToCustomerDetail = (item) => {
    this.props.navigation.navigate("CustomerDetail",{item});      //Alert.alert(item);//
  }
  render() {
    const { loading, data } = this.state;
    const { customers } = this.props;

    return (
      <View style={{ flex: 1, backgroundColor: '#fff' }}>
        <SearchBar
          loading={loading}
          onPressSearch={this.onPressSearch}
        />

        <List containerStyle={{ borderTopWidth: 0, borderBottomWidth: 0 }}>
          <FlatList
            data={data}
            renderItem={({ item }) => {
              const badge = {
                value: `☆ ${item.custstar}`, {/* d is a database field*/}
                badgeContainerStyle: { right: 10, backgroundColor: '#56579B' },
                badgeTextStyle: { fontSize: 12 },
              };  

              return (
                 <TouchableOpacity onPress={this.goToCustomerDetail.bind(this, item.custid)}>
                  <ListItem
                    style={{backgroundColor: 'transparent'}}
                    roundAvatar
                    title={`${item.custid}`}
                    subtitle={item.custname}
                    avatar={{ uri: item.imageurl }}
                    badge={badge}
                    containerStyle={{ borderBottomWidth: 1 }}

                  />
                 </TouchableOpacity>
              );
            }
            }
            keyExtractor={item => item.custid}
            ItemSeparatorComponent={this.renderSeparator}
            ListHeaderComponent={this.renderHeader}
            ListFooterComponent={this.renderFooter}
            onRefresh={this.handleRefresh}
            refreshing={this.state.refreshing}
            onEndReached={this.handleLoadMore}
            onEndReachedThreshold={0.5}
          />
        </List>
      </View>
    );
  }
}

SearchBar.js

import React, { Component } from 'react';
import { View, TextInput } from 'react-native';
import { Button } from 'react-native-elements';

class SearchBar extends Component {
  state = { term: '' };

  render() {
    const {
      containerStyle,
      searchTextStyle,
      buttonStyle
    } = styles;

    return (
      <View style={containerStyle}>
        <TextInput
          style={searchTextStyle}
          underlineColorAndroid='transparent'
          placeholder='Search'
          onChangeText={term => this.setState({ term })}
          value={this.state.term}
          autoFocus={ true }
        />
        <Button
          buttonStyle={buttonStyle}
          icon={{name: 'search', size: 24}}
          title={this.props.loading ? 'Searching...' : 'Search'}
          onPress={() => this.props.onPressSearch(this.state.term)}
        />
      </View>
    );
  }
}

const styles = {
  containerStyle: {
    marginTop: 25,
    marginLeft: 10,
    marginRight: 10,
    flexDirection: 'row',
    backgroundColor: 'transparent'
  },
  searchTextStyle: {
    flex: 1,
    borderBottomWidth: 1,
    borderBottomColor: '#BE3A31'
  },
  buttonStyle: {
    height: 30,
    marginBottom: 8,
    backgroundColor: '#BE3A31'
  }
};


export default SearchBar;

当然,您有以下情况:“ CustomerDetail”组件具有三个选项卡,需要从“ CustomerDetail”父组件获取“ custid”,因此有必要让“ CustomerDetail”组件知道此信息,您已经创建了'App.js'组件,并在StackNavigator中定义了'CustomerDetail','CustomerDetail'组件仅通过以下几行代码即可获取此信息:

之前

CustomerDetail: {
        screen: CustomerDetail,
        navigationOptions: {
          title:'Customer Detail'
        }
      }

CustomerDetail: {
    screen: CustomerDetail,
    navigationOptions: ({navigation}) => ({
      title:'Customer Detail',
      custid: navigation.state.params.custid
    })
  }

现在,您可以通过以下行从“ CustomerDetail”组件中获取“ custid”信息,即标签中的子项:

class CustomerDetail extends Component {

render () {
    const { customers } = this.props;
    let custid = this.props.navigation.state.params.custid;

    return(
        <TabNavigator style={styles.container}>
           <TabNavigator.Item
            title={customers[custid].name}
           </TabNavigator.Item>
        </TabNavigator>
    )
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM