rgommezz / react-native-scroll-bottom-sheet

Cross platform scrollable bottom sheet with virtualisation support, native animations at 60 FPS and fully implemented in JS land :fire:
MIT License
1.54k stars 64 forks source link

onPress event on Handle not detected when ScrollBottomSheet is closed (100%) #65

Open LetUsGeek opened 3 years ago

LetUsGeek commented 3 years ago

Current Behavior

I'm pretty new in react-native so maybe I missed it. Anyway the ScrollBottomSheet seems working OK. I wanted to add the possibility to open (respectively close) fully the ScrollBottomSheet when I tap on the handle while the bottome sheet is closed (respectively open).

So display the handle through TouchableOpacity and detect onPress event on which I call the function snapTo of my ScrollBottomSheet depending on the current index provided by onSettle event.

The onSettle event works on all snapping Points, however the onPress event does not work when the ScrollBottomSheet is closed.

My component:

import React, { createRef } from 'react';
import { Dimensions, StyleSheet, Text, Image, View, TouchableOpacity } from 'react-native';
import ScrollBottomSheet from 'react-native-scroll-bottom-sheet';

const DEVICE_HEIGHT = Dimensions.get('screen').height;
const WINDOW_HEIGHT = Dimensions.get('window').height;

const windowHeight = Dimensions.get('window').height;
const windowWidth = Dimensions.get('window').width;
const space_btw_items = 5;
const item_width = 70;
const bottomSheetRef = createRef()    //Un crée une ref de composant pour plus tard
class ScrollStack extends React.Component {
  constructor(props) {
    super(props)
     this.state = {
       imageSource: Array.from({ length: 200 })
     }
  }

  _getNumberOfColumns = () => {   //Retourne le nombre de colonnes max en fonction du tel 
    return(
      Math.floor((windowWidth-space_btw_items) / (item_width + space_btw_items),0)
    )
  }

  render() {
    return (
      <View style={styles.container} 
        >
        <ScrollBottomSheet // If you are using TS, that'll infer the renderItem `item` type
          ref={bottomSheetRef}    //On donne un nom à notre composant ScrollBottomSheet pour l'appeler plus tard
          componentType="FlatList"
          snapPoints={['0%', '100%']} //{[top of the screen, pas d'autre point d'arrêt 'xx%', windowHeight-28 = windowHeight - hauteur de la poignée]}
          initialSnapIndex={1} // 1 pour commencer en bas
          topInset={140-(DEVICE_HEIGHT-WINDOW_HEIGHT)} //C'est pour remonter la stack list de 80(HScrollList) + 20 (poignée de la StackList) - 6 (ça je sais pas pourquoi)
          numColumns={ this._getNumberOfColumns() }
          //friction={1}
          onSettle={(index) => {
            currentIdex = index
            //console.log(index)
          }}
          renderHandle={() => (
            <TouchableOpacity 
              style={styles.header}
              onPress={() => {
                console.log("event detected, current index is "+currentIdex+". I launch command snapTo to the index "+((currentIdex == 1) ? 0: 1));
                bottomSheetRef.current?.snapTo((currentIdex == 1) ? 0: 1);
              }}
              >
              <View style={styles.panelHandle}/>
              <View style={styles.panelHandle2}/>
            </TouchableOpacity>
          )}
          data={this.state.imageSource.map((_, i) => String(i))}
          keyExtractor={i => i}
          renderItem={({ item }) => (
            <TouchableOpacity 
              style={styles.item}
              onPress={() => {
               console.log("onPress detected on item")
              }} 
              onLongPress={() => {
                console.log("longPress detected on item")
              }}
            >
              <Text>{item}</Text>
            </TouchableOpacity>
          )}
          contentContainerStyle={styles.contentContainerStyle}
          extraData={this.state}
          //disableScrollViewPanResponder={true}
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    zIndex: 20,
  },
  contentContainerStyle: {
    padding: space_btw_items,
    backgroundColor: '#F3F4F9',
    justifyContent: 'space-between',
    alignItems: 'center',
  },
  header: {
    alignItems: 'center',
    backgroundColor: '#CCCCCC',
    opacity: 1,
    height:20,
    paddingVertical: 7, //hauteur entre le haut du header et la première poignée
    borderTopLeftRadius: 20,
    borderTopRightRadius: 20
  },
  panelHandle: {
    width: 80,
    height: 2,
    backgroundColor: 'white',
    marginBottom: 2,    //espacement entre les deux poignées
    borderRadius: 1
  },
  panelHandle2: {
    width: 80,
    height: 2,
    backgroundColor: 'white',
    borderRadius: 1
  },
  item: {
    //padding: 2,
    justifyContent: 'center',
    backgroundColor: '#D3D3D3',
    alignItems: 'center',
    margin: space_btw_items/2,
    width: item_width,
    height: item_width,
    borderRadius: 10,
    opacity: 0.8,
  },
});

export default ScrollStack;

Expected Behavior

I expect the onPress event when my ScrollBottomSheet is closed to be detected so I can just by one tap open the list immediately.

How to reproduce

This not an expo project. The code above should work to reproduce my issue.

Your Environment

Test on Android My dependencies:

  "dependencies": {
    "@react-navigation/bottom-tabs": "^5.11.10",
    "@react-navigation/native": "^5.9.4",
    "@react-navigation/stack": "^5.14.4",
    "react": "17.0.1",
    "react-native": "0.64.0",
    "react-native-android-immersive-mode": "^1.3.0",
    "react-native-draggable-flatlist": "^2.6.1",
    "react-native-gesture-handler": "^1.10.3",
    "react-native-paper": "^4.8.1",
    "react-native-reanimated": "^2.0.0",
    "react-native-safe-area-context": "^3.2.0",
    "react-native-screens": "^3.1.1",
    "react-native-scroll-bottom-sheet": "^0.7.0",
    "react-native-svg": "^12.1.1",
    "react-native-svg-transformer": "^0.14.3",
    "react-native-vector-icons": "^8.1.0",
    "react-redux": "^7.2.4",
    "redux": "^4.1.0",
    "transcript": "0.0.6"
  },
LetUsGeek commented 3 years ago

I'd like to add that it seems that snapTo() function only works the very first time. Indeed I want the bottom list to close after an item is selected (via an onPress event). The snapTo function only works the first time avec application opening.

Anybody understand why?