Реагируйте на собственную выставку - перейдите от FlatList к подробному экрану - PullRequest
0 голосов
/ 21 января 2020

Реагирует на родную ладью ie здесь. Я пытаюсь приспособить приложение с вкладками React Native expo к своим потребностям в обучении. В настоящее время я работаю над плоскими списками и хочу открыть новый экран при повторном отправлении любого элемента отправки FlatList в качестве параметра для реквизита элемента. Я достиг определенной точки, но, похоже, не смог ее успешно выполнить.

HomeScreen. js

import * as WebBrowser from 'expo-web-browser';
import React from 'react';
import {Image,Platform,ScrollView,StyleSheet,Text,TouchableOpacity,View,} from 'react-native';
import { SafeAreaView } from 'react-native';
import SearchableFlatList from '../navigation/SearchableList';
import { MonoText } from '../components/StyledText';

export default function HomeScreen() {
    return (
        <SafeAreaView style={{ flex: 1, backgroundColor: '#fff' }}>
            <SearchableFlatList/>
        </SafeAreaView>
    );
}

class LogoTitle extends React.Component {
    render() {
        return (
            <React.Fragment>
                <Image
                    source={require('../assets/images/icon.png')}
                    style={{ width: 30, height: 30 }}
                />
                <Text style={{ fontSize: 30 }}>
                    AgriPrices
                </Text>
            </React.Fragment>
        );
    }
}

HomeScreen.navigationOptions = {
    headerTitle: () => <LogoTitle />,
    headerStyle: {backgroundColor: '#f4511e',},
    headerTintColor: '#fff',
    headerTitleStyle: {fontWeight: 'bold',},
};

MainTabNavigator. js

import React from 'react';
import { Platform } from 'react-native';
import { createStackNavigator } from 'react-navigation-stack';
import { createBottomTabNavigator } from 'react-navigation-tabs';
import TabBarIcon from '../components/TabBarIcon';
import HomeScreen from '../screens/HomeScreen';
import LinksScreen from '../screens/LinksScreen';
import SettingsScreen from '../screens/SettingsScreen';

const config = Platform.select({web: { headerMode: 'screen' },default: {},});

const HomeStack = createStackNavigator({Home: HomeScreen,},config);
HomeStack.navigationOptions = {
  tabBarLabel: 'Home',
  tabBarIcon: ({ focused }) => (<TabBarIcon focused={focused} name={Platform.OS === 'ios' ? `ios-home${focused ? '' : '-outline'}` : 'md-home'}/>),
};
HomeStack.path = '';

const LinksStack = createStackNavigator({Links: LinksScreen,},config);
LinksStack.navigationOptions = {
  tabBarLabel: 'Info',
  tabBarIcon: ({ focused }) => (<TabBarIcon focused={focused} name={Platform.OS === 'ios' ? `ios-information-circle${focused ? '' : '-outline'}` : 'md-information-circle'}/>),
};
LinksStack.path = '';

const SettingsStack = createStackNavigator({Settings: SettingsScreen,},config);
SettingsStack.navigationOptions = {
  tabBarLabel: 'Settings',
  tabBarIcon: ({ focused }) => (<TabBarIcon focused={focused} name={Platform.OS === 'ios' ? 'ios-settings' : 'md-settings'} />),
};
SettingsStack.path = '';

const tabNavigator = createBottomTabNavigator({HomeStack,SettingsStack,LinksStack,});
tabNavigator.path = '';

export default tabNavigator;

SearchableFlatlist . js

import React, { Component } from 'react';
import { View, Text, FlatList, ActivityIndicator, Alert } from 'react-native';
import { ListItem, SearchBar } from 'react-native-elements';
import DetailsScreen from '../screens/DetailsScreen';

class MyFlatList extends Component {
  constructor(props) {
    super(props);
    this.state = {
      loading: false,
      data: [],
      error: null,
    };
    this.arrayholder = [];
  }

  componentDidMount() {
    this.makeRemoteRequest();
  }

  makeRemoteRequest = () => {
    const url = 'http://dummyurl.com';
    this.setState({ loading: true });
    fetch(url)
      .then(res => res.json())
      .then(res => {
        this.setState({data: res,error: res.error || null,loading: false,});
        this.arrayholder = res;
      })
      .catch(error => {
        this.setState({ error, loading: false });
      });
  };

  renderSeparator = () => {
    return (
      <View
        style={{
          height: 1,
          width: '86%',
          backgroundColor: '#CED0CE',
          marginLeft: '14%',
        }}
      />
    );
  };

  searchFilterFunction = text => {
    this.setState({
      value: text,
    });
    const newData = this.arrayholder.filter(item => {
      const itemData = `${item.description.toUpperCase()} ${item.product.toUpperCase()} ${item.product.toUpperCase()}`;
      const textData = text.toUpperCase();
      return itemData.indexOf(textData) > -1;
    });
    this.setState({
      data: newData,
    });
  };

  _onPress(item) {
    this.props.navigation.navigate('Details', {product: item.product,description: item.description,});
  }

  renderHeader = () => {
    return (
      <SearchBar
        placeholder="Type Here..."
        lightTheme
        round
        onChangeText={text => this.searchFilterFunction(text)}
        autoCorrect={false}
        value={this.state.value}
      />
    );
  };

  render() {
    if (this.state.loading) {
      return (
        <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
          <ActivityIndicator />
        </View>
      );
    }
    const myicons = [
      {title: 'Cotton',file: require('../assets/images/cotton.png'),},
      {title: 'Beef',file: require('../assets/images/beef.png'),},
      {title: 'Bananas',file: require('../assets/images/banana.png'),},
      {title: 'Butter',file: require('../assets/images/butter.png'),},
      {title: 'Cocoa',file: require('../assets/images/cocoa.png'),},
      {title: 'Coffee',file: require('../assets/images/coffee.png'),},
      {title: 'Corn',file: require('../assets/images/corn.png'),},
      {title: 'Cotton',file: require('../assets/images/cotton.png'),},
      {title: 'Eggs',file: require('../assets/images/eggs.png'),},
      {title: 'Meat',file: require('../assets/images/meat.png'),},
      {title: 'Milk',file: require('../assets/images/milk.png'),},
      {title: 'Oils',file: require('../assets/images/oil.png'),},
      {title: 'Oranges',file: require('../assets/images/orange.png'),},
      {title: 'Rice',file: require('../assets/images/rice.png'),},
      {title: 'Shrimps',file: require('../assets/images/shrimp.png'),},
      {title: 'Sugar',file: require('../assets/images/sugar.png'),},
      {title: 'Tea',file: require('../assets/images/tea.png'),},
      {title: 'Tobacco',file: require('../assets/images/tobacco.png'),},
      {title: 'Wheat',file: require('../assets/images/wheat.png'),},
      {title: 'Wool',file: require('../assets/images/wool.png'),},
      {title: 'Oats',file: require('../assets/images/oat.png'),},
      {title: 'Indexes',file: require('../assets/images/index.png'),},
    ];
    const { navigate } = this.props.navigation;
    return (
      <View style={{ flex: 1 }}>
        <FlatList
          data={this.state.data}
          renderItem={({ item }) => (
            <ListItem
              leftAvatar={{ source: myicons.filter(myitem => myitem.title === item.product)[0].file }}
              title={item.description}
              rightTitle={item.price.toString()}
              subtitle={item.date}
              onPress={() => navigate('Details', { product: item.product })}
            />
          )}
          keyExtractor={item => item.description}
          ItemSeparatorComponent={this.renderSeparator}
          ListHeaderComponent={this.renderHeader}
        />
      </View>
    );
  }
}

export default MyFlatList;

DetailsScreen. js

import React from 'react';
import {Text, Image,ScrollView, StyleSheet } from 'react-native';

export default function DetailsScreen() {
  var product =this.props.navigation.getParam('product', 'No Name'); //second parameter is a callback
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>The product is {this.props.navigation.state.params.product||'NoName'} /*NoName is also a callback*/</Text>
    </View>
  );
}

DetailsScreen.navigationOptions = {
  headerTitle: () => <LogoTitle />,
    headerStyle: {
      backgroundColor: '#f4511e',
    },
    headerTintColor: '#fff',
    headerTitleStyle: {
      fontWeight: 'bold',
    },
};

class LogoTitle extends React.Component {
  render() {
    return (
      <React.Fragment>
          <Image
            source={require('../assets/images/icon.png')}
            style={{ width: 30, height: 30 }}
          />
          <Text style={{ fontSize: 30 }}>
            AgriPrices
        </Text>
      </React.Fragment>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    paddingTop: 15,
    backgroundColor: '#fff',
  },
});

Мне нужно открыть DetailsScreen при нажатии элемента SearchableFlatList на HomeScreen передавая в качестве параметра описание . С кодом выше я получаю ошибку undefined не является объектом (оценивая 'this.props.navigation.navigate') . Как я могу превзойти это?

1 Ответ

1 голос
/ 21 января 2020

Я бы посоветовал вам обернуть MyFlatList и DetailsScreen стековым навигатором.

const finalStack = createStackNavigator(
{
    MyFlatList: MyFlatList,
    DetailsScreen: DetailsScreen
},
{
    headerMode: 'none'
});

После того, как вы это сделаете, 'this.props.navigation.navigate' не будет неопределенным. На данный момент между этими двумя экранами нет навигационной ссылки.

В: Почему я выбираю стековый навигатор? A: Поскольку вы не хотите, чтобы FlatList неоднократно отображался на переключателе экрана.

...