Vertical position of close button on paywall on Android does not match design
- [x] I have updated Purchases SDK to the latest version
- [x] I have read the Contribution Guidelines
- [x] I have searched the Community
- [x] I have read docs.revenuecat.com
- [x] I have searched for existing Github issues
Describe the bug
This is one of the paywalls that we have designed using your paywall editor:
and this is what it looks like on Android:
the same design looks like this on an iOS device:
As you can see, the top of the paywall seems to be chopped off on Android and it displays the safe area on Android. In addition, we had to move the close button down quite a lot in order for it to appear in the rendered version on Android.
Due to this, we have had to create two separate versions of our paywall - one for iOS devices and one for Android devices. We would like to be able to have just a single design that works on both iOS and Android correctly.
This is a snippet of the code we use to render your paywall:
export const RevenueCatPaywallContainer = (): JSX.Element => {
...
return (
<View style={styles.container}>
<RevenueCatUI.Paywall
key={`paywall-${forceRenderKey}`}
onPurchaseCompleted={onPurchaseCompleted}
onPurchaseStarted={onPurchaseStarted}
onDismiss={onDismiss}
options={{ offering: selectedOffering }}
/>
</View>
);
};
const styles = StyleSheet.create({
container: tailwind("flex-1"),
});
- Environment
- Platform: Expo 52 with React Native (not new architecture)
- SDK version: 8.11.3
- OS version: iOS 18.5, Android 14
- Xcode/Android Studio version:
- React Native version: 0.76.9
- SDK installation (CocoaPods + version or manual):
- How widespread is the issue. Percentage of devices affected. 100%
- Debug logs that reproduce the issue
- Steps to reproduce, with a description of expected vs. actual behavior
- Other information (e.g. stacktraces, related issues, suggestions how to fix, links for us to have context, eg. stackoverflow, etc.)
Additional context The paywalls we design via your web page seem to match what we see on iOS devices. Its just Android devices that seem to have the issue.
👀 We've just linked this issue to our internal tracker and notified the team. Thank you for reporting, we're checking this out!
Sorry - looks like the chopping off at the top of the paywall on Android was an issue in our own code - apologies. So its just the position of the close button that is incorrect on Android as seen here:
Hi @asnaseer I'd be happy to help with this. Looking at your paywall it actually appears that your current design matches what you are seeing on the device, the close button appears to be the same spot. Are you still running into this discrepancy?
We had to move the close button down in the actual design for it to appear as above on the actual Android device. This is what the RevenueCat Paywall design actually looks like as described above:
If fact, even on the iOS device, the close button appears a little higher than where it was in the design:
@HaleyRevcat Any further updates on this?
@HaleyRevcat We are also seeing this issue on Android in our app when trying to use RevenueCat paywalls. In our case it is particularly noticeable when using the Paywall component, instead of presentPaywall. For our use case we need the component.
So what seems to happen is:
presentPaywall iOS: Paywall is presented like a modal "sheet" and there is proper padding in the top for the close button.
presentPaywall Android: Paywall is presented like a "full screen modal" and the statusbar is not translucent so the content won't be behind the status bar. Maybe not the most beautiful but at least there is proper padding in the close button top.
Paywall component on iOS: the paywall is able to entirely fill the screen and it's aware of the safe area. There is proper padding on top of the close button.
Paywall component on Android [❌ here is where the issue is]: the paywall will fill the screen but there is definetly not enough padding on top of the Close button. It's positioned too far to the top.
It is likely not considering the "safe area" inset in the top.
The workaround is to wrap with a SafeArea but it doesn't look good since there will be a visible solid status bar. It should behave like on iOS, where it's able to render content behind the status bar which looks good and consistent with the design in the dashboard and should still able to handle the safe area inset in the top.
Here is a comparison for the same paywall, using a premade paywall starter template from Revenuecat (V2 paywall), without any modifications of my own:
1 - iOS 18 device using presentPaywall:
2 - Android 14 device using presentPaywall:
3 - iOS 18 device using the Paywall component (PurchasesUI.Paywall):
4 - Android 14 device using the Paywall component (PurchasesUI.Paywall) ❌ :
Notice how the close button goes too far to the top, different from iOS. Making it harder to reach/press and not looking as good.
We are also seeing this issue on Android in our app when trying to use RevenueCat paywalls. In our case it is particularly noticeable when using the Paywall component, instead of presentPaywall. For our use case we need the component...
An update on this. I realized when I remove the provider from react-native-keyboard-controller that my app uses I am not able to reproduce it anymore.
We also use react-native-edge-to-edge and If in the Paywall screen I force the System bars to be hidden
import { SystemBars } from 'react-native-edge-to-edge';
<SystemBars style={'dark'} hidden={true} />
Then it helps with the issue since there won't be any status bar to account for in the top and the content is completely full screen. Of course ideally it should be able to be aware of the statusbar presence.
So at the moment it is not fully clear to me if the issue is with the Revenuecat sdk itself that is doing something problematic in terms of handling statusbar presence with edge-to-edge display since the only place where i have this issue is with the revcat paywall or if the issue is with the packages that are managing android edge-to-edge display (react-native-edge-to-edge / react-native-keyboard-controller).
I'll add updates if I discover something new.
I'll add updates if I discover something new.
@HaleyRevcat
After some investigation I think I was able to find what is happening in react-native-keyboard-controller that was affecting the paywall and I opened an issue there: https://github.com/kirillzyusko/react-native-keyboard-controller/issues/1013.
I am not entirely sure if it is something that the Revenuecat sdk should be able to address for, but it doesn't seem like. Might be worth having a look on your end to see if it makes sense to be an issue there or if Revcat should also do something in the sdk.
Obviously here I'm referring to my own case which can be a different one from the issue author.
@asnaseer
Maybe check if you are also using react-native-keyboard-controller on your app. If yes, it's probably the same issue as me. If not, then it's something else on your case.
@leonardorib In my case we are not using react-native-keyboard-controller. Our latest code for displaying the revcat paywall looks like this:
...
return (
<View style={styles.container}>
<StatusBar style="dark" backgroundColor="#FFFFFF00" />
<RevenueCatUI.Paywall
key={`paywall-${forceRenderKey}`}
onPurchaseCompleted={onPurchaseCompleted}
onPurchaseStarted={onPurchaseStarted}
onDismiss={onDismiss}
options={{ offering: selectedOffering }}
/>
</View>
);
};
const styles = StyleSheet.create({
container: tailwind("flex-1"),
});
This is rendered directly in a screen that we navigate to when the user touches a specific call-to-action button in our app.
@leonardorib We now do use react-native-keyboard-controller with a translucent StatusBar and are still suffering from this issue.
@HaleyRevcat Any updates on this?
Hi @asnaseer apologies for the lack of response here, this ticket's notifications did not reach me but I have flagged it to now keep better track of this.
If you use our most recent React Native SDK 9.2.0 here are you still experiencing this issue? Or if you'd rather not use Google Billing 8 yet then do you see this on 8.11.10 here? In the meantime I will be investigating this with the paywalls team and will get back to you on what we find.
Sorry again for the delay!
@leonardorib We now do use
react-native-keyboard-controllerwith a translucentStatusBarand are still suffering from this issue.@HaleyRevcat Any updates on this?
@asnaseer In case you or anyone else is facing this issue because of react-native-keyboard-controller, what worked for us was patching the package with this change:
https://github.com/fit52-digital/react-native-keyboard-controller/commit/8d803169088661d035a35dbecdc64a3f238741fe
For more information on this: https://github.com/kirillzyusko/react-native-keyboard-controller/issues/1013
@HaleyRevcat We are currently using 8.11.9 but I just tried 8.11.10 and it has the same issue. I then tried 9.2.0 and that also has the same issue.
Just out of curiosity, how would Google Billing 8 affect us?
@leonardorib Thanks for the suggestions - I will try that out as well.
@leonardorib Your patch seems to have done the trick! Many thanks again 👍
@HaleyRevcat With the patched version of the react-native-keyboard-controller library, we no longer need to create separate paywalls for Android vs iOS. It might be worth documenting this somewhere in your docs so others can also benefit.