Skip to content

Override shouldDelayChildPressedState in Android containers - #57127

Closed
j-piasecki wants to merge 1 commit into
react:mainfrom
j-piasecki:export-D108003374
Closed

j-piasecki wants to merge 1 commit into
react:mainfrom
j-piasecki:export-D108003374

Conversation

@j-piasecki

Copy link
Copy Markdown
Contributor

Summary:
Changelog: [Android][Fixed] Prevent React Native containers from delaying native touches

shouldDelayChildPressedState returns true for compatibility reasons and non-scrollable containers should override it and return false to prevent the press feedback from being delayed.

Differential Revision: D108003374

Summary:
Changelog: [Android][Fixed] Prevent React Native containers from delaying native touches

[`shouldDelayChildPressedState`](https://developer.android.com/reference/android/view/ViewGroup#shouldDelayChildPressedState%28%29) returns `true` for compatibility reasons and non-scrollable containers should override it and return `false` to prevent the press feedback from being delayed.

Differential Revision: D108003374
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Jun 9, 2026
@facebook-github-tools facebook-github-tools Bot added p: Software Mansion Partner: Software Mansion Partner labels Jun 9, 2026
@facebook-github-tools facebook-github-tools Bot added the p: Facebook Partner: Facebook label Jun 9, 2026
@meta-codesync

meta-codesync Bot commented Jun 9, 2026

Copy link
Copy Markdown

@j-piasecki has exported this pull request. If you are a Meta employee, you can view the originating Diff in D108003374.

meta-codesync Bot pushed a commit that referenced this pull request Jun 12, 2026
Summary:
X-link: #57127

Changelog: [Android][Fixed] Prevent React Native containers from delaying native touches

[`shouldDelayChildPressedState`](https://developer.android.com/reference/android/view/ViewGroup#shouldDelayChildPressedState%28%29) returns `true` for compatibility reasons and non-scrollable containers should override it and return `false` to prevent the press feedback from being delayed.

Reviewed By: javache

Differential Revision: D108003374

fbshipit-source-id: 5c9cff01a088b09d3de27396a834ee370ae740ce
@j-piasecki j-piasecki closed this by deleting the head repository Jun 17, 2026
j-piasecki added a commit to software-mansion/react-native-gesture-handler that referenced this pull request Jul 6, 2026
## Description

react/react-native#57127 added an override for
`shouldDelayChildPressedState` in React Native containers to prevent
them from delaying the pressed state in children. All components
extending them will get this for free, but our button implementation
doesn't extend `ReactViewGroup` but `ViewGroup`.

This PR adds override for `shouldDelayChildPressedState` in
`RNGestureHandlerButtonViewManager`.
m-bert pushed a commit to software-mansion/react-native-gesture-handler that referenced this pull request Sep 11, 2026
react/react-native#57127 added an override for
`shouldDelayChildPressedState` in React Native containers to prevent
them from delaying the pressed state in children. All components
extending them will get this for free, but our button implementation
doesn't extend `ReactViewGroup` but `ViewGroup`.

This PR adds override for `shouldDelayChildPressedState` in
`RNGestureHandlerButtonViewManager`.
j-piasecki added a commit to software-mansion/react-native-screens that referenced this pull request Oct 2, 2026
…pressed state

[`shouldDelayChildPressedState`](https://developer.android.com/reference/android/view/ViewGroup#shouldDelayChildPressedState%28%29) returns `true` by default and should be overridden by non-scrolling containers to return false. Having it return `true` causes a slight delay before showing interaction feedback on native buttons.

Related: react/react-native#57127, software-mansion/react-native-gesture-handler#4296

Adds `shouldDelayChildPressedState` override to the legacy (`legacy/`) container views and to `TabsScreen`. `ScreensCoordinatorLayout` keeps delaying the pressed state when presented as a form sheet, since the sheet is draggable. These changes are kept separate so they can be cherry-picked to the legacy branch.
j-piasecki added a commit to software-mansion/react-native-screens that referenced this pull request Oct 2, 2026
## Description

[`shouldDelayChildPressedState`](https://developer.android.com/reference/android/view/ViewGroup#shouldDelayChildPressedState%28%29) returns `true` by default and should be overridden by non-scrolling containers to return false. Having it return `true` causes a slight delay before showing interaction feedback on native buttons.

Related: react/react-native#57127, software-mansion/react-native-gesture-handler#4296

I'm not sure whether the decisions behind when to simply return `false` and when to make it conditional make sense. Generally, when something is scrollable/draggable, it should return true. Let me know if I missed anything.

## Changes

Adds `shouldDelayChildPressedState` override to container views.

## Before & after - visual documentation

Video at 1/4 speed

https://github.com/user-attachments/assets/d6021082-a96d-4a37-8c9b-832e33393232

## Test plan

<details>
<summary>Tested using Gesture Handler 3 `Touchable`</summary>

```jsx
import React from 'react';
import { StatusBar, StyleSheet, Text, View } from 'react-native';
import {
  GestureHandlerRootView,
  Touchable,
} from 'react-native-gesture-handler';
import {
  Screen,
  ScreenStack,
  ScreenStackHeaderConfig,
} from 'react-native-screens';

export default function TouchablePressedState() {
  return (
    <GestureHandlerRootView style={styles.root}>
      <StatusBar hidden />
      <ScreenStack style={styles.root}>
        <Screen activityState={2} stackAnimation="none" style={styles.root}>
          <ScreenStackHeaderConfig hidden />
          <View style={styles.content}>
            <Text style={styles.eyebrow}>ANDROID · NATIVE STACK</Text>
            <Text style={styles.title}>Pressed state timing</Text>
            <Text style={styles.description}>
              Hold the button. The Android touch circle marks contact; blue
              marks the native pressed feedback.
            </Text>
            <Touchable
              testID="pressed-state-touchable"
              accessibilityLabel="Hold to show pressed feedback"
              animationDuration={0}
              underlayColor="#2563eb"
              activeUnderlayOpacity={1}
              style={styles.button}
              onPress={() => {}}>
              <Text style={styles.buttonText}>PRESS AND HOLD</Text>
            </Touchable>
            <Text style={styles.detail}>RNGH 3 Touchable</Text>
            <Text style={styles.code}>animationDuration={0}</Text>
            <Text style={styles.footnote}>
              Same screen and held gesture in both builds. Only the Screens
              native overrides change.
            </Text>
          </View>
        </Screen>
      </ScreenStack>
    </GestureHandlerRootView>
  );
}

const styles = StyleSheet.create({
  root: { flex: 1, backgroundColor: '#0f172a' },
  content: { flex: 1, justifyContent: 'center', padding: 28 },
  eyebrow: {
    color: '#94a3b8',
    fontSize: 12,
    fontWeight: '700',
    letterSpacing: 2,
  },
  title: { color: '#f8fafc', fontSize: 30, fontWeight: '700', marginTop: 12 },
  description: {
    color: '#cbd5e1',
    fontSize: 16,
    lineHeight: 24,
    marginTop: 16,
  },
  button: {
    height: 148,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#334155',
    borderRadius: 18,
    marginTop: 36,
    marginBottom: 28,
  },
  buttonText: { color: '#ffffff', fontSize: 20, fontWeight: '700' },
  detail: { color: '#cbd5e1', fontSize: 15 },
  code: {
    color: '#93c5fd',
    fontFamily: 'monospace',
    fontSize: 15,
    marginTop: 6,
  },
  footnote: { color: '#94a3b8', fontSize: 13, lineHeight: 20, marginTop: 28 },
});

```

</details>

## Checklist

- [x] Included code example that can be used to test this change.
- [x] For visual changes, included screenshots / GIFs / recordings documenting the change.
- [x] For API changes, updated relevant public types.
- [x] Ensured that CI passes
kkafar pushed a commit to software-mansion/react-native-screens that referenced this pull request Oct 9, 2026
…pressed state (#4771)

[`shouldDelayChildPressedState`](https://developer.android.com/reference/android/view/ViewGroup#shouldDelayChildPressedState%28%29)
returns `true` by default and should be overridden by non-scrolling
containers to return false. Having it return `true` causes a slight
delay before showing interaction feedback on native buttons.

Related: react/react-native#57127,
software-mansion/react-native-gesture-handler#4296

Adds `shouldDelayChildPressedState` override to the legacy (`legacy/`)
container views and to `TabsScreen`. `ScreensCoordinatorLayout` keeps
delaying the pressed state when presented as a form sheet, since the
sheet is draggable. These changes are kept separate so they can be
cherry-picked to the legacy branch.
kkafar pushed a commit to software-mansion/react-native-screens that referenced this pull request Oct 9, 2026
## Description

[`shouldDelayChildPressedState`](https://developer.android.com/reference/android/view/ViewGroup#shouldDelayChildPressedState%28%29) returns `true` by default and should be overridden by non-scrolling containers to return false. Having it return `true` causes a slight delay before showing interaction feedback on native buttons.

Related: react/react-native#57127, software-mansion/react-native-gesture-handler#4296

I'm not sure whether the decisions behind when to simply return `false` and when to make it conditional make sense. Generally, when something is scrollable/draggable, it should return true. Let me know if I missed anything.

## Changes

Adds `shouldDelayChildPressedState` override to container views.

## Before & after - visual documentation

Video at 1/4 speed

https://github.com/user-attachments/assets/d6021082-a96d-4a37-8c9b-832e33393232

## Test plan

<details>
<summary>Tested using Gesture Handler 3 `Touchable`</summary>

```jsx
import React from 'react';
import { StatusBar, StyleSheet, Text, View } from 'react-native';
import {
  GestureHandlerRootView,
  Touchable,
} from 'react-native-gesture-handler';
import {
  Screen,
  ScreenStack,
  ScreenStackHeaderConfig,
} from 'react-native-screens';

export default function TouchablePressedState() {
  return (
    <GestureHandlerRootView style={styles.root}>
      <StatusBar hidden />
      <ScreenStack style={styles.root}>
        <Screen activityState={2} stackAnimation="none" style={styles.root}>
          <ScreenStackHeaderConfig hidden />
          <View style={styles.content}>
            <Text style={styles.eyebrow}>ANDROID · NATIVE STACK</Text>
            <Text style={styles.title}>Pressed state timing</Text>
            <Text style={styles.description}>
              Hold the button. The Android touch circle marks contact; blue
              marks the native pressed feedback.
            </Text>
            <Touchable
              testID="pressed-state-touchable"
              accessibilityLabel="Hold to show pressed feedback"
              animationDuration={0}
              underlayColor="#2563eb"
              activeUnderlayOpacity={1}
              style={styles.button}
              onPress={() => {}}>
              <Text style={styles.buttonText}>PRESS AND HOLD</Text>
            </Touchable>
            <Text style={styles.detail}>RNGH 3 Touchable</Text>
            <Text style={styles.code}>animationDuration={0}</Text>
            <Text style={styles.footnote}>
              Same screen and held gesture in both builds. Only the Screens
              native overrides change.
            </Text>
          </View>
        </Screen>
      </ScreenStack>
    </GestureHandlerRootView>
  );
}

const styles = StyleSheet.create({
  root: { flex: 1, backgroundColor: '#0f172a' },
  content: { flex: 1, justifyContent: 'center', padding: 28 },
  eyebrow: {
    color: '#94a3b8',
    fontSize: 12,
    fontWeight: '700',
    letterSpacing: 2,
  },
  title: { color: '#f8fafc', fontSize: 30, fontWeight: '700', marginTop: 12 },
  description: {
    color: '#cbd5e1',
    fontSize: 16,
    lineHeight: 24,
    marginTop: 16,
  },
  button: {
    height: 148,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#334155',
    borderRadius: 18,
    marginTop: 36,
    marginBottom: 28,
  },
  buttonText: { color: '#ffffff', fontSize: 20, fontWeight: '700' },
  detail: { color: '#cbd5e1', fontSize: 15 },
  code: {
    color: '#93c5fd',
    fontFamily: 'monospace',
    fontSize: 15,
    marginTop: 6,
  },
  footnote: { color: '#94a3b8', fontSize: 13, lineHeight: 20, marginTop: 28 },
});

```

</details>

## Checklist

- [x] Included code example that can be used to test this change.
- [x] For visual changes, included screenshots / GIFs / recordings documenting the change.
- [x] For API changes, updated relevant public types.
- [x] Ensured that CI passes
t0maboro added a commit to software-mansion/react-native-screens that referenced this pull request Oct 12, 2026
…pressed state (#4771) (#4864)

[`shouldDelayChildPressedState`](https://developer.android.com/reference/android/view/ViewGroup#shouldDelayChildPressedState%28%29)
returns `true` by default and should be overridden by non-scrolling
containers to return false. Having it return `true` causes a slight
delay before showing interaction feedback on native buttons.

Related: react/react-native#57127,

software-mansion/react-native-gesture-handler#4296

Adds `shouldDelayChildPressedState` override to the legacy (`legacy/`)
container views and to `TabsScreen`. `ScreensCoordinatorLayout` keeps
delaying the pressed state when presented as a form sheet, since the
sheet is draggable. These changes are kept separate so they can be
cherry-picked to the legacy branch.

(cherry picked from commit cc069e6)

Co-authored-by: Jakub Piasecki <jakub.piasecki@swmansion.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. meta-exported p: Facebook Partner: Facebook p: Software Mansion Partner: Software Mansion Partner

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant