LayoutAnimation

LayoutAnimation announces that the next layout pass should be animated; you then change state, and every view that appears, moves, resizes or disappears animates to its new frame, with nothing to wire up. configureNext() takes a config (a duration plus create, update and delete sections, each with a type such as 'spring' or 'easeInEaseOut' and a property such as 'opacity') and two optional callbacks. Presets: easeInEaseOut (300 ms), linear (500 ms) and spring (700 ms).

src/anim/Expand.tsx: animate the next layout, then change state (excerpt)TSX
// The old Android opt-in; on the New Architecture it only prints a warning
if (Platform.OS === 'android') UIManager.setLayoutAnimationEnabledExperimental?.(true);
// ...inside Expand, called when a card is tapped:
  const toggle = (id: number) => {
    resetClock();
    LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut,
      () => log('layout animation ended'), () => log('layout animation failed'));
    setOpen(open === id ? null : id);            // the next layout pass is animated
    log('state set, open =', open === id ? null : id);
  };
Output
 WARN  setLayoutAnimationEnabledExperimental is currently a no-op in the New Architecture.
 LOG  +2ms state set, open = 1
 LOG  +361ms layout animation ended
 LOG  +1ms state set, open = null
 LOG  +332ms layout animation ended

Two taps opened and closed the first card. The warning settles what older tutorials leave open: their opt-in line was needed on Android's old architecture only, so delete it. The catch is scope: the animation applies to every layout change in that pass and cannot follow a gesture; Layout Animations has a more controlled tool.