question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Elevation does not animate when it is inside a view which animates its opacity (Android P)

See original GitHub issue

Environment

  React Native Environment Info:
    System:
      OS: macOS 10.14.1
      CPU: x64 Intel(R) Core(TM) i5-8259U CPU @ 2.30GHz
      Memory: 40.65 MB / 16.00 GB
      Shell: 5.6.2 - /usr/local/bin/zsh
    Binaries:
      Node: 10.11.0 - ~/.nvm/versions/node/v10.11.0/bin/node
      Yarn: 1.13.0 - ~/.nvm/versions/node/v10.11.0/bin/yarn
      npm: 6.5.0 - ~/.nvm/versions/node/v10.11.0/bin/npm
      Watchman: 4.9.0 - /usr/local/bin/watchman
    SDKs:
      iOS SDK:
        Platforms: iOS 11.4, macOS 10.13, tvOS 11.4, watchOS 4.3
      Android SDK:
        Build Tools: 23.0.1, 26.0.2, 26.0.3, 27.0.2, 27.0.3, 28.0.1, 28.0.2, 28.0.3
        API Levels: 22, 23, 24, 25, 26, 27, 28
    IDEs:
      Android Studio: 3.3 AI-182.5107.16.33.5199772
      Xcode: 9.4.1/9F2000 - /usr/bin/xcodebuild
    npmPackages:
      react: 16.6.3 => 16.6.3
      react-native: 0.59.0 => 0.59.0
    npmGlobalPackages:
      react-native-cli: 2.0.1

Description

What described in the title works in any Android but not on Android P. See the differences:

Android P:

androidp

Below Android P:

notandroidp

Reproducible Demo

https://snack.expo.io/@satya164/elevation-issue---android-p

This can affect libraries like react-navigation when a new screen comes in animating its opacity. See https://github.com/react-navigation/react-navigation/issues/5535.

Can be found here also https://github.com/ferrannp/react-native-elevation-animation-android-pie with react-native 0.59.X.

Issue Analytics

  • State:open
  • Created 5 years ago
  • Reactions:92
  • Comments:63 (4 by maintainers)

github_iconTop GitHub Comments

46reactions
RichardLindhoutcommented, Aug 10, 2019

Buy an iPhone and never get this issue again 😉

42reactions
DomiRcommented, Aug 5, 2020

My issue: https://github.com/react-navigation/react-navigation/issues/8676

On android, setting a view’s opacity will render artifacts when child views have elevation.

So I’ve investigated this issue and came to the conclusion, that this is an android intended behavior.

Background:

<View style={{opacity: 0.5}}>
	<View style={{elevation: 5, margin: 10, backgroundColor: 'red'}}>
<View>

To understand this issue we let’s dig into react code. Both views will get a BaseViewManager, which holds a reference to a ReactViewGroup.ReactViewGroup subclasses a ViewGroup and not an Android View (because it can have children). When setting a backgroundColor to a ReactViewGroup it creates a ReactViewBackgroundDrawable which subclasses a Drawable and sets it as background. The creation happens in getOrCreateReactViewBackground which composes any already existing background drawable (maybe images use this, in all my test cases the existing drawable was always null) with the new background using LayerDrawable.

Problem: Now when setting an alpha value (changing opacity) it will do this on the ReactViewGroup directly but not on the background drawable, which is why we have the artifact. As react-native per default set hasOverlappingRendering to false to save memory, this problem is an expected android performance optimization. It seems that some devices do not perform the optimization and I only experienced this when changing the alpha after the first render. See android docs for what this flag does.

In the screenshot below you can see the different parameters (plain android project in this repo, not react-native, although I used the same ReactViewBackgroundDrawable class from react-native which I just extracted and patched to get it running). There are 6 red 100x100 boxes that get the opacity set on their view or for testing purposes on their background drawable. Within a red box a yellow box is placed with elevation set to 10. In the first row, hasOverlappingRendering is disabled.

screenshot

Repo: https://github.com/DomiR/react-native-opacity-issue So as you can see on both boxes on the right-hand side setting opacity only on the background is not enough, as all children will still have full opacity. Setting alpha both on the background and on the view itself will result in 0.25 opacity for the background. On the left-hand side is what we really want but we need to hasOverlappingRendering enabled like in the left bottom.

Solution: I don’t know if there is a solution that is good for everyone. As you can see from the screenshot we need to set hasOverlappingRendering but doing so per default is not performant (facebook blog entry).

Fortunately, we can set this flag using needsOffscreenAlphaCompositing as a view prop.

As @kmagiera mentioned that you should probably enable this only temporarily during animations. The react-native docs also mention using renderToHardwareTextureAndroid in combination.

PS: What also should work is setting the opacity value for all children as well.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Animation | Jetpack Compose - Android Developers
AnimatedVisibility waits until all animations in the Transition have finished before removing its content. For exit animations created independent of Transition ...
Read more >
Advanced Flutter Animations – Staggered Animations, Tween ...
In the case of animations, i.e. for implicitly animated widgets, we can ... no tween, no animation and yet it animates to the...
Read more >
SceneView | API Reference | ArcGIS Maps SDK for JavaScript ...
For animating the view, see goTo(). If set in the constructor, this property will be ignored if the viewpoint, camera, or extent properties...
Read more >
An Easy Way to Create Complex Animations in MotionLayout
android :alpha; android:elevation; android:rotation; android:rotationX; android:rotationY; transitionPathRotate — rotates view relative to its ...
Read more >
Apply shadow or blur effects – Figma Help Center
You may have to adjust the opacity of your layers to get the desired effect.If you set a layer's opacity to 100%, you...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found