skip to Main Content

For
"react-native": "^0.70.5"

Requirement:

  • Flatlist as an overlay above Clickable elements
  • Flatlist header has a transparent area, with pointerEvents="none" to make the elements below clickable and yet allow the Flatlist to scroll.
    enter image description here

Issues with some possible approaches

  1. pointerEvents="none" doesn’t work with Flatlist, as internally how Flatlist is built it will block the events at all values of pointerEvents. It’s the same with Scrollview as well.
  2. react-native-touch-through-view (the exact library I need) doesn’t work with RN 0.70.2, library is outdated. After fixing the build issues, touch events are not propagating to the clickable elements.
  3. Created a custom component ScrollableView, as pointerEvents with View work well. With this adding pointerEvents to none on parts of the children, lets the touch event to propagate to elements below.
  • This is working well on Android, but failing on iOS.
  • Also the scrolling of the view is not smooth.
  • Requires further handling for performance optimisation for long lists
import React, { useState, useRef } from 'react';
import { View, PanResponder, Animated } from 'react-native';

const ScrollableView = ({children, style, onScroll}) => {
    const scrollY = useRef(new Animated.Value(0)).current;
    const lastScrollY = useRef(0);
    const scrollYClamped = Animated.diffClamp(scrollY, 0, 1000);

    const panResponder = useRef(
        PanResponder.create({
            onStartShouldSetPanResponder: () => true,
            onPanResponderMove: (_, gestureState) => {
                scrollY.setValue(lastScrollY.current + gestureState.dy);
            },
            onPanResponderRelease: (_, { vy, dy }) => {
                lastScrollY.current += dy;
                Animated.spring(scrollY, {
                    toValue: lastScrollY.current,
                    velocity: vy,
                    tension: 2,
                    friction: 8,
                    useNativeDriver: false,
                }).start();
            },

        })
    ).current;

    const combinedStyle = [
        {
            transform: [{ translateY: scrollYClamped }],
        },
        style
    ];

    return (
        <Animated.View
            {...panResponder.panHandlers}
            pointerEvents="box-none"
            style={combinedStyle}
        >
            {children}
        </Animated.View>
    );
};

export default ScrollableView;

Any solution to any of the above three approaches is appreciated.

2

Answers


  1. if you are looking to get help building your custom component, I would suggest uploading the entire code including your flatlist, or creating a codesandbox and sharing the link.

    however, to achieve what you trying to do I would use
    https://github.com/gorhom/react-native-bottom-sheet npm package.
    with this, you can achieve what you want with much ease and convenience.

    Login or Signup to reply.
  2. If you are using Flatlist for this, you may need to do this approach, because it seems like the problem is in the display of the elements

    Use bottom sheet library here

    Use this the library FlashList which is faster and more customizable that Flatlist.

    the benefit of using these libraries is that you don’t need to do your own animation and it would save you a lot of issues/bugs that you could face, and it would fix the issue you are facing since both libraries support and tested on android/ios

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search