Course contentsShow
← React Native
Lesson 347 of 1,5554. Flexbox and Native StylingFree lesson

Gestures for Resizing Panels

Implement a split-pane layout where the divider position can be adjusted by the user.

In this lesson, you will learn how to create a responsive split-pane interface where users can drag a central divider to resize two adjacent panels dynamically.

The Logic of Dynamic Splitting

When building a resizable panel, we think of the layout as a parent container holding two children. Instead of using hard-coded flex values, we use a sharedValue (typically from react-native-reanimated) to represent the width or height of the first panel.

The divider acts as our "handle." We attach a GestureDetector to this handle, capturing the user's touch movement. As the user drags, we update the sharedValue, which triggers a re-render of our layout dimensions. Because we are optimizing for performance, we apply these changes directly to the style object of our components to ensure fluid movement.

Implementation Example

Imagine a horizontal split-pane where the first panel’s width is controlled by panelWidth:

const panelWidth = useSharedValue(200);

const gesture = Gesture.Pan()
  .onUpdate((event) => {
    // Constrain the resize to the screen bounds
    panelWidth.value = Math.max(50, Math.min(event.absoluteX, 300));
  });

return (
  <View style={styles.container}>
    <Animated.View style={{ width: panelWidth }} />
    <GestureDetector gesture={gesture}>
      <View style={styles.divider} />
    </GestureDetector>
    <View style={styles.rightPanel} />
  </View>
);

Critical Layout Considerations

When the user drags the divider, the layout engine has to recalculate the positions of all siblings. To keep this performant:

  1. Avoid State for Geometry: Do not use useState to track the exact pixel movement during a drag. Updating React state causes re-renders that can cause jank. Use useSharedValue to drive the layout update at the UI thread level.
  2. Constrain Inputs: Always clamp your gesture values. If a user drags the divider completely off-screen, your layout may break or hide components entirely.
  3. Handle Threading: Since this is a layout-intensive task, ensure that your styling updates respect the "Native Driver" concepts we’ve previously discussed, allowing the UI thread to handle the transformation without blocking the JavaScript thread.

Key Takeaway: Use shared values to drive width or height properties directly in response to Pan gestures, ensuring the layout remains reactive without the overhead of standard React state updates.