Now sometimes it can be cumbersome to add a bunch of such checks
and here we already have three checks on the header for example,
certainly something we can add but maybe not optimal.
Instead to keep our style objects cleaner, we could set up a base header here, for example header base
and then add headerIOS and headerAndroid and now what we do is we take all these styles which change
based on the platform out of the base style,
add them here to headerIOS and headerAndroid and on headerIOS,
we only keep the iOS look here, so white,
then this color for the border at the bottom and a pixel width of one for that border
and here on Android, we remove this check and keep color primary as a background color and on the other
hand, we get rid of our border by using these values or by entirely removing that and not setting it
at all.
Now we just need to make sure we add headerIOS or headerAndroid and for that, we can go up here and
set up up our styles object where we merge in all our header base styles now,
so these are always set but now in addition, we can merge in the result of platform select which now
is a method which takes an object where we have to specify an iOS key and point at the value or
in this case, the object we want to use if we are on iOS which is styles.headerIOS and add an Android
key and point at styles that headerAndroid
and with that we're telling React Native please merge in the properties of the value, in this case, an
object we're selecting for iOS and for Android.
So you'll always have to pass an object to platform select and then you have different values for iOS and
Android and the value here could also be a number, just wouldn't work here because here we actually expect
an object so that we can pull out all the property value pairs and pass them to our surrounding style.
So here a number doesn't make sense but you can use select with any kind of value,
here we just need an object,
so we're pointing at the headerIOS and the headerAndroid objects. And with that, we're having leaner code,
we have leaner styles down there and then we have code with a base style where we then use platform
select to dynamically pick different styles based on the platform we're running on and therefore now,
we have the same look as before but now in a more elegant way. Another place in our app where we could
take advantage of this is our main button here. Our main button looks and feels the same on both platforms
which isn't horrible but which also might not be what we want.
If we go to our MainButton.js file, we see we always use touchable opacity here but actually on Android,
we might want to use the ripple effect.
Now thankfully, React Native has the touchable native feedback component built in which actually gives
us a touchable object which has a built-in ripple effect,
so we want to use that on Android and touchable opacity on iOS.
Now of course, we can use the platform API which we therefore also have to import from React Native to
use a different component here based on the platform
and for that we can use a really neat feature React has not React Native specific but we can use it
in React in general,
we can set up a variable which starts with a capital character so that we can use it as a jsx element
because only capital character variables can be used as jsx elements and we name this let's say button
component, the name is totally up to you and by default, that's touchable opacity.
So I point at the touchable opacity object here, without angled brackets, just pointing at it like this.
Now we can add an if check and check if platform OS is equal to Android and important, also check something
else on platform,
also check if platform version is greater or equal to 21 because only Android API version 21
or higher supports the ripple effect.
So if both is true, then we'll set button component to touchable native feedback so then we'll use the
one with the ripple effect, otherwise we'll use the one with the opacity effect.
So if we're on Android and the Android version is high enough, it's 21 or higher, then we use touchable
native feedback. Now because I name this with a capital starting character, we can use this here instead
of touchable opacity in our jsx code, looks strange at first but will work perfectly fine. If we now save
this and this restarts, you'll see now here you have that ripple effect, you can see it if we press and
hold, you see that ripple effect on the button. Doesn't look perfect yet because it's actually rectangular
and doesn't respect our border radius and we'll fix that but it works
and on the other hand here on iOS, we have the opacity effect as you can tell if you press this.
So now let's fix the border radius and we can do so by wrapping this with another view and that's
just a little hack, a little workaround you need to be aware of.
We wrap this with another view where I set a style of let's say button container,
add that style down there in our stylesheet and on that button container here which is now wrapped
around everything,
I set the same border radius as I set on the button, so 25 in this case here and I add overflow hidden
which means that any child component that would go beyond the boundaries of this components, so of the component
with this style is basically clipped and this will ensure that the ripple effect which is now a child
component of this view will be clipped on the rounded edges of this button.
So now if we save this and we retry this, you will see that the ripple effect only fills out the button,
which of course looks way better and on iOS of course, we still have the same behaviour as before.
So using the platform here in an if check is also something we can do but
we can also use this neat trick here to render totally different components based on the platform we're
running on.