开发者问题收集

如何从 FlatList 导航到新屏幕?

2019-07-22
74

我希望在单击 FlatList 中的项目时导航到名为 GridVid 的屏幕。我不知道该如何做,因为

onPress={() => this.props.navigation.navigate('GridVid')}

只有在 App.js 中调用才有效,因为 StackNavigator 就是在那里定义的,而不是 ListItem 类(位于名为 ListItem.js 的单独文件中)

//App.js

class SettingsClass extends Component {

    constructor(props) {
      super(props)

      this.state = {
        columns: 3, //Columns for Grid
      };   
    }


  render() {
     const {columns} = this.state
      return (

         <View style={styles.grid}>
            <FlatList
                  numColumns={columns}         
                  data={[
                    {uri:'https://randomuser.me/api/portraits/thumb/women/12.jpg'},
                    {uri:'https://randomuser.me/api/portraits/thumb/women/13.jpg'},
                    {uri:'https://randomuser.me/api/portraits/thumb/women/14.jpg'},
                  ]}
                  renderItem={({item}) => {            
                      return (<ListItem itemWidth={(ITEM_WIDTH-(10*columns))/columns} 
                                        image={item}                                           
                              />                                
                            )
                       }}
                  keyExtractor={
                     (index) => { return index } 
                  } 
            />
         </View>
      );
  }
}

//Settings Class swipes to GridVid
const SettingsStack = createStackNavigator({
  SettingsScreen: {
    screen: SettingsClass
  },
  GridVid: {
    screen: GridVidClass
  },
});

//ListItem.js

export default class ListItem extends Component {

    state = {
       animatepress: new Animated.Value(1)
    }

    animateIn() {
        Animated.timing(this.state.animatepress, {
            toValue: 0.90,
            duration: 200
        }).start()
    }

    animateOut() {
      Animated.timing(this.state.animatepress, {
          toValue: 1,
          duration: 200
      }).start()
  }   

    render() {
      const {itemWidth} = this.props
      return (
          <TouchableWithoutFeedback
             onPressIn={() => this.animateIn()}
             onPressOut={() => this.animateOut()} 
             onPress={() => this.props.navigation.navigate('GridVid')} //WONT WORK HERE in this file!!!!
             >       
             <Animated.View style={{
                margin:5,
                transform: [{scale: this.state.animatepress}] }}>

                  <Image style={{width:itemWidth, height: 100}} source={this.props.image}></Image>   

             </Animated.View>
          </TouchableWithoutFeedback>

        );
    }

  }

//GridVid.js

export default class GridVidClass extends Component {

    render() {
      return (
        <View style={styles.container}> 
             <Text>On GridVid </Text>

        </View> 
        );
    }

  }

有没有办法在 FlatList 中(或 App.js 中的任何位置)调用 onPress={() => this.props.navigation.navigate('GridVid') ,而不是在 ListItem 中(目前无法在那里工作)?然而在 ListItem 中,至少我单击了我想要的图像并且对我所单击的内容有一些参考。

2个回答

您需要做的是将 onPress 属性传递给您的 ListItem ,以使导航发生。

//App.js

class SettingsClass extends Component {

    constructor(props) {
      super(props)

      this.state = {
        columns: 3, //Columns for Grid
      };   
    }


  render() {
     const {columns} = this.state
      return (

         <View style={styles.grid}>
            <FlatList
                  numColumns={columns}         
                  data={[
                    {uri:'https://randomuser.me/api/portraits/thumb/women/12.jpg'},
                    {uri:'https://randomuser.me/api/portraits/thumb/women/13.jpg'},
                    {uri:'https://randomuser.me/api/portraits/thumb/women/14.jpg'},
                  ]}
                  renderItem={({item}) => {            
                      return (<ListItem itemWidth={(ITEM_WIDTH-(10*columns))/columns} 
                                        image={item}        
                                        onPress={() => this.props.navigation.navigate('GridVid') // passing the onPress prop 
                              />                                
                            )
                       }}
                  keyExtractor={
                     (index) => { return index } 
                  } 
            />
         </View>
      );
  }
}

//Settings Class swipes to GridVid
const SettingsStack = createStackNavigator({
  SettingsScreen: {
    screen: SettingsClass
  },
  GridVid: {
    screen: GridVidClass
  },
});

//ListItem.js

export default class ListItem extends Component {

    state = {
       animatepress: new Animated.Value(1)
    }

    animateIn() {
        Animated.timing(this.state.animatepress, {
            toValue: 0.90,
            duration: 200
        }).start()
    }

    animateOut() {
      Animated.timing(this.state.animatepress, {
          toValue: 1,
          duration: 200
      }).start()
  }   

    render() {
      const {itemWidth} = this.props
      return (
          <TouchableWithoutFeedback
             onPressIn={() => this.animateIn()}
             onPressOut={() => this.animateOut()} 
             onPress={this.props.onPress} // using onPress prop to navigate
             >       
             <Animated.View style={{
                margin:5,
                transform: [{scale: this.state.animatepress}] }}>

                  <Image style={{width:itemWidth, height: 100}} source={this.props.image}></Image>   

             </Animated.View>
          </TouchableWithoutFeedback>

        );
    }

  }
Vencovsky
2019-07-22

ListItem 不在 StackNavigator 中,所以它不知道什么是导航

你可以像 Vencovsky 的答案那样去做,或者从 ListItem 的父组件传递导航属性

<ListItem 
   itemWidth={(ITEM_WIDTH-(10*columns))/columns} 
   image={item} 
   navigation={this.props.navigation}                                   
/>
cuongtd
2019-07-22