facebook / react-native

A framework for building native applications using React
https://reactnative.dev
MIT License
118.09k stars 24.19k forks source link

[0.61.*] Broken shadow on android #26544

Closed mikebouwmans closed 1 year ago

mikebouwmans commented 4 years ago

Looks like shadow/elevation is broken on android on react-native@0.61.*, see pictures below

It only happens when the https://github.com/santomegonzalo/react-native-floating-action is being used. I'm not able to reproduce it without this.

To receive the expected result uncomment App.js:25-35 and restart react-native using react-native run-android.

It looks like other packages have this problem aswell, eg callstack/react-native-paper#1341 ,

React Native version: System: OS: Windows 10 CPU: (8) x64 Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz Memory: 3.25 GB / 15.86 GB Binaries: Node: 11.9.0 - C:\Program Files\nodejs\node.EXE Yarn: 1.12.3 - C:\Program Files (x86)\Yarn\bin\yarn.CMD npm: 6.10.1 - C:\Users\bouwm\AppData\Roaming\npm\npm.CMD IDEs: Android Studio: Version 3.4.0.0 AI-183.6156.11.34.5692245

Steps To Reproduce

  1. clone the git repo
  2. run npm install and react-native run-android

Describe what you expected to happen: The circle in the middle should look like this: Screenshot_1569261819

But it looks like this: Screenshot_1569261858

Snack, code example, screenshot, or link to a repository:

Git repo: https://github.com/mikebouwmans/ShadowTest

marcorm commented 4 years ago

Hi @mikebouwmans , does it happen for you with every API level? For me only with Android API Level 26

forsen commented 4 years ago

I took the liberty to create a minimal example repository which demonstrates the issue without using third party libraries: https://github.com/forsen/shadowTest

This is how the repository is created:

  1. react-native init
  2. Upgrade from v0.60.5 to v0.61.0-rc.3 per rn-diff-purge instructions
  3. Add a circular view with elevation
B27 commented 4 years ago

@forsen unfortunately, this repository will not help to reproduce the bug You showed normal behavior of the shadows. Since you did not specify backgroundColor in styles.circle, we see the shadow as it is drawn under the view. Start your example on any version react-native and everything will work just as well

mikebouwmans commented 4 years ago

Hi @mikebouwmans , does it happen for you with every API level? For me only with Android API Level 26

I will check this later today

B27 commented 4 years ago

I met with this issue about a week ago. I use the react-navigation and react-navigation-stack libraries and after upgrading to rn 0.61.0-rc.0 I noticed that when I switch from the root screen to any other, the views disappear, the shadows are drawn on top of the modal screens and the background is drawn on the outlined TextInput ( from the react-native-paper library). However, after making any screen root, everything in it is rendered correctly. After enumerating different style values, I found the reason for the view to break: if view has a borderRadius other than undefined, then when switching to another screen, the view with borderRadius is rendered under all other views, even if you specify zIndex. Until you reload, all views on all screens with borderRadius (including the root) will be broken. For this reason, it seems that the bug is associated with shadows, but everything is fine with them :)

To reproduce this bug, I created a repository https://github.com/B27/React-Native-borderRadius-test based on rn-diff-purge (branch release/0.61.0-rc.3). The project contains two screens with the same content. After switching to the second screen, the modal window and the other views with borderRadius break until you set their borderRadius to undefined

The following screenshots are from api 28 (also tested on api 21, 25 with the same result)

Normal:

With bugs:

Bug suppression by setting borderRadius to undefined:

marcorm commented 4 years ago

Setting borderRadius on Modal to undefined also solves the react-native-paper Dialog issue

ScreamZ commented 4 years ago

Is it related to https://github.com/styled-components/css-to-react-native/issues/117 ? I though it was specific for styled components but I'm experiencing strange issues with background and positions relative since 0.61-rcX

zwenza commented 4 years ago

I could reproduce the exact same issue just using a <TouchableOpacity/> which contains a circular <View />. The View has a shadow on it too.

When you press the element it becomes transparent and shows the exact same issue. Can reproduce that already with RN 0.60.5 on Android, iOS looks fine.

billouboq commented 4 years ago

I have the same issue on react native 0.59.10 so that's not something new I guess :/

B27 commented 4 years ago

@zwenza, @billouboq you are talking about normal shadow behavior in android not related to this issue. Android and iOS implementation of shadows are very different, even for this they use different properties in styles (abstract elevation on Android, and CSS-like properties in iOS).

I could reproduce the exact same issue just using a <TouchableOpacity/> which contains a circular <View />. The View has a shadow on it too.

I created a new project with react-native 0.54.4 added <TouchableOpacity /> containing <View /> and saw the same. Because it is not a bug. In android, if you want to use shadows + transparency, you always need to add an opaque backgroundColor for the View, or if you want to use transparency, then wrap it in an opaque View.

zwenza commented 4 years ago

In android, if you want to use shadows + transparency, you always need to add an opaque backgroundColor for the View, or if you want to use transparency, then wrap it in an opaque View.

Thanks @B27 , will give this a try today!

B27 commented 4 years ago

@zwenza I forgot that for TouchableOpacity there is a simpler way - apply elevation to TouchableOpacity itself. Instead of <TouchableOpacity> <View style={stylesWithElevation} /> </TouchableOpacity> use <TouchableOpacity style={elevationStyle}> <View style={viewStyle} /> </TouchableOpacity>

ScreamZ commented 4 years ago

@gaearon Looks like a serious bug that went though the net :p On android.

I think the minimal example of React native isn't enough to detect those kind of issue between versions and too many people are updating to rc to test :(

B27 commented 4 years ago

Since it is not immediately clear what the problem is (https://github.com/facebook/react-native/issues/26544#issuecomment-534616069), I recorded a video of the application from the repository https://github.com/B27/React-Native-borderRadius-test showing a bug: https://www.youtube.com/watch?v=wA6H2m153Yg Let me remind you that the screens are exactly the same (FirstScreen and SecondScreen use the same BugScreen component inside)

ScreamZ commented 4 years ago

As i Posted in the linked topic here: https://github.com/styled-components/css-to-react-native/issues/117

Here is an small example with a border radius (it's commented but try with uncommenting it)

const Bug = () => {
  return (
    <View style={{ flex: 1 }}>
      <BuggingView />
      <PageWrapper>
        <Text>
          This should appear above backgroundThis should appear above background This should appear above background This should appear
          above above background This should appear above background This should appear above background This should appear above background
          This This should appear above background This should appear above background This should appear above background This should
          appear above background This should appear above background This should appear above background This should appear above
          background This should appear above background This should appear above background This should appear above background This should
          appear above background This should appear above background This should appear above background This should appear above
          background This should appear above background This should appear above background This should appear above background This should
          appear above background This should appear above background This should appear above background This should appear above
          background This should appear above background
        </Text>
      </PageWrapper>
    </View>
  );
};

const BuggingView = styled.View`
  height: 200;
  position: absolute;
  background-color: blue;
  top: 0;
  right: 0;
  left: 0;
`;
const PageWrapper = styled.View`
  background-color: red;
  padding: 20px;
  /* border-radius: 8px; */
  flex: 1;
  margin: 20px;
`;

The red box text is going front, and the red is missing behind the blue.

definitely related to border-radius on 0.61 (was also not working in rc-3)

samiede commented 4 years ago

Can confirm that it has something to do with borderRadius!

ScreamZ commented 4 years ago

Yes, indeed the problem is about:

One of those (or all of them) is having issue with android since 0.61.x

EDIT: @B27 Elements with borderRadius as if losing their zIndex

B27 commented 4 years ago

Updating from 0.60.5 to 0.61.1 also caused something similar in our app, but only for Views that are positioned absolutely.

remove borderRadius on button and it will be in the foreground again

B27 commented 4 years ago

@ScreamZ borderRadius only Elements with borderRadius as if losing their zIndex Just an absolute position is used to draw elements on top of others, but this can also be achieved using margin or padding

samiede commented 4 years ago

In 0.61.1 it works when applied on a white background

karvulf commented 4 years ago

Same problem here, would be awesome it this problem gets a quick fix

albullington commented 4 years ago

I'm experiencing this in a few different situations:

This happened when I upgraded to 0.61.1 from 0.60.5. Everything shows up as expected on iOS.

gdoudeng commented 4 years ago

I am facing this problem and hope to solve it as soon as possible.

mjmasn commented 4 years ago

Reproduction: https://github.com/mjmasn/ElevationIssue60 (working) https://github.com/mjmasn/ElevationIssue61 (broken)

Rapsssito commented 4 years ago

Forcing borderRadius attribute to undefined fixes the glitch. Libraries like react-native-paper or react-native-modal use this attribute with predetermined values on their elements, that is why the bug is manifesting there.

ScreamZ commented 4 years ago

https://github.com/react-native-community/releases/issues/146#issuecomment-536548800

grabbou commented 4 years ago

https://github.com/react-native-community/releases/issues/146#issuecomment-537006467

Regression has been introduced by this change: https://github.com/facebook/react-native/commit/14b455f69a30d128db384749347f41b03b9a6000

mjmasn commented 4 years ago

Shame that it broke everything as that sounds like a really nice fix for a longstanding problem with ripples + border radius :thinking:

grabbou commented 4 years ago

Yeah, @mjmasn, hopefully, there's another fix soon.

Just submitted a PR #26682 with a rollback, once merged, this issue will be automatically closed.

alexeyvax commented 4 years ago

Seems like I found workaround. You heed to repeat borderRadius prop. There is my code:

<TouchableOpacity
  style={styles.button}
  onPress={onPress}
>
  <View style={styles.iconWrapper}>
    <Icon
      size={14}
      name="share"
      color="#fff"
    />
  </View>
</TouchableOpacity>

and styles

button: {
  position: 'absolute',
  bottom: 10,
  right: 10,
  width: 40,
  height: 40,
  borderRadius: 40, // set borderRadius here
},
iconWrapper: {
  display: 'flex',
  justifyContent: 'center',
  alignItems: 'center',
  width: '100%',
  height: '100%',
  backgroundColor: 'rgba(72, 150, 242, .9)',
  borderRadius: 40, // repeat borderRadius here
},
ScreamZ commented 4 years ago

https://github.com/facebook/react-native/issues/26544#issuecomment-541458632

Not a workaround I think you lose the benefit of shadow box and Elevation doing like this.

alexeyvax commented 4 years ago

@ScreamZ Yes, I agree with you, but I believe it is a temporary solution until guys fix this issue.

VehpuS commented 4 years ago

Was this the issue mentioned in the 0.61.2 release notes: https://github.com/facebook/react-native/releases/tag/v0.61.2 ? If so - shouldn't it be closed?

cuongtora1996 commented 4 years ago

For some reason, I still get this in android image I used version 0.61.2.

danielbonifacio commented 4 years ago

Very frustrating get these errors and know that the maintainer team just ignores it like 4 months.

el173 commented 4 years ago

In which version was this fixed?

Frans-L commented 4 years ago

Seems to be same issue: https://github.com/facebook/react-native/issues/25093

fqborges commented 4 years ago

I can confirm v0.61.2 fixes the absolute+ borderRadius undesired effect on zIndex.

UmeshBaldaniya46 commented 4 years ago

I have same issues after update 0.61.5

initially my project is in RN 0.57.0, due to 64-bit i have to update RN version so i have made it 0.60.5

So i getting same issues as above, i have read above comment @samiede to resolved in 0.61.1

Now i have updated my whole code RN in 0.61.5 , but issues is till there

RN in 0.57.0 Screenshot_2020-02-18-15-35-44

RN in 0.61.5 Screenshot_2020-02-18-15-32-43

"react": "16.9.0", "react-native": "0.61.5", "@react-native-community/datetimepicker": "^2.2.1", "@react-native-community/masked-view": "^0.1.6", "aws-sdk": "^2.610.0", "base-64": "^0.1.0", "locutus": "^2.0.11", "moment": "^2.24.0",

`<KeyboardAvoidingView keyboardVerticalOffset={Platform.select({ ios: 0, android: 50 })} behavior={(Platform.OS === 'ios') ? "padding" : null} enabled style={{ flex: 1, backgroundColor: "#fff" }}> <SimpleActionBarWithTitle title={" " + Strings.Title_Scan_Rego} handleBackButtonClick={this.handleBackButtonClick} /> <Loader loading={(this.state.isProcessing || this.props.scanRegoJobDetailsData.isLoading) && (!this.props.unAuthorizedReducer.isUnAuthorised)} /> <Image style={{ height: "60%" }} source={{ uri: this.props.navigation.state.params.uri }} />

{ this.setState({ rego: value }) }} InputProps={{ disableUnderline: true }} underlineColorAndroid="transparent" />
            <View style={{ flex: 1, flexDirection: "row" }}>
                <TouchableOpacity
                    style={[styles.saveButtonStyle, { marginLeft: "15%", backgroundColor: "#c3c3c3", }]}
                    activeOpacity={0.5}
                    onPress={() => this.onRetakeImageScreen()}>
                    <Text style={{ color: "#fff", textAlign: "center", fontSize: 20 }}>
                        {Strings.Label_Retry}
                    </Text>
                </TouchableOpacity>
                <TouchableOpacity
                    style={[styles.saveButtonStyle, { marginRight: "15%" }]}
                    activeOpacity={0.5}
                    onPress={() => this.onJobDetailsScreen()}>
                    <Text style={{ color: "#fff", textAlign: "center", fontSize: 20 }}>
                        {Strings.Next}
                    </Text>
                </TouchableOpacity>
            </View>
        </KeyboardAvoidingView>`

`textInputStyle: { paddingHorizontal: 16, fontSize: 19, minWidth: 120, color: colors.black, fontWeight: 'bold',

},
textInputMainView: {
    justifyContent: "center",
    backgroundColor: "#fff",
    alignItems: 'center',
    borderWidth: 1,
    borderColor: "#fff",
    height: 60,
    borderRadius: 100,
    marginTop: 20,
    marginBottom: 5,
    marginLeft: '15%',
    marginRight: '15%',
    ...Platform.select({
        ios: {
            shadowColor: 'rgba(0,0,0, 0.4)',
            shadowOffset: { height: 3, width: 0 },
            shadowOpacity: 0.7,
            shadowRadius: 5
        },
        android: {
            elevation: 4,
        }
    }),
},
saveButtonStyle: {
    height: 48,
    flex: 1,
    marginHorizontal: 10,
    marginTop: 20,
    marginBottom: 10,
    backgroundColor: 'rgba(21, 221, 241, 1)',
    borderRadius: 100,
    justifyContent: "center",
    ...Platform.select({
        ios: {
            shadowColor: 'rgba(0,0,0, 0.4)',
            shadowOffset: { height: 3, width: 0 },
            shadowOpacity: 0.7,
            shadowRadius: 5
        },
        android: {
            elevation: 4,
        }
    }),
},`

If any one have any solution without change in code, Please let me know, bcz my project is so much large

SimonFricker commented 4 years ago

Has this bug been open 5 months already?

ess3nt commented 4 years ago

Have the same issue devices: samsung s9+, s10+ android version: 10 react-native: 0.61.5

on android 8.1.0 looks good

atefeh-mt commented 4 years ago

set activeOpacity to 1 on parent TouchableOpacity will fix it. activeOpacity={1}

AndreiAyar commented 4 years ago

Still not fixed.

Shadow Android: unknown

Shadow on Ios using Elevation:3 (tried from 1 to event 20, still the same) image0

johneyo commented 4 years ago

just set elevation to 0

samiede commented 4 years ago

just set elevation to 0

How does that solve anything?

ammoradi commented 4 years ago

I'm also facing this issue on "react-native": "0.62.2"

PawarSharadB commented 4 years ago

I am having the same issue in "0.61.4" On long press button on TouchableOpacity i am getting a unwanted shadow like a pentagon on my circled button .

byteab commented 4 years ago

just add a backgroundColor: "#fff" property

fabOnReact commented 4 years ago

can't find a reproducible example to solve this Issue. This post unluckily includes several message, but NO CLEAR REQUIREMENT

Better close this issue and open a new one with clear explanation of the issue. Thanks

jongoh-lee commented 4 years ago

it is interesting that this bug appears optionally odd buttons is fine but even buttons show octagon

Screenshot_1594879626 Screenshot_1594879630