React-native animation lagging on android - react-native

I'm using the Reanimated library(2.2.0), and I have a fairly simple animation to expand a Animated.View , that I call when pressing a TouchableOpacity:
height.value = withTiming(calculatedHeight, {
duration: 300,
easing: Easing.inOut(Easing.ease),
});
On IOS is running very nice on 60fps, but on some Android phones like Samsung S20,S21 Ultra, the animation is lagging a lot. I tried it on an older Samsung(A5) and on it is running fine again. Any suggestions are appreciated.

Animate the Y scale instead of the height. left top width height are slow

Related

Animated flatlist interpolate issue when app moves into the background

When using react-native animated flatlist to create a carousel, all works fine with the interpolate as follows:
const translateY = this.state.scrollX.interpolate({ inputRange, outputRange: [0, -60, 0] });
But, when we call out to a separate intent for permissions or going off to a settings page, the X position of my animated flatlist appears to reset to 0 and the object I'm animating (in a carousel) drops to the bottom of the view.
Has anyone got any idea on how to handle that? I don't know if it's because the scrollX state setting is lost or what...
Thanks
Simon
Just in case anyone else is using the Animated.FlatList in a similar way to us, the issue related to the useNativeDriver setting. When set to true and the app was put into the background with an React Native Intent, the FlatList flatlined and lost it's interpolated Y coordinate. When setting to false, things worked as expected.
Thanks
Simon

How do I handle scaling issues in a React Native app between tvOS and Android TV?

Native resolution for Apple TV seems to be 1920x1080 (as expected) but for Android TV / Fire TV it seems to be 961.5022957581195x540.8450413639423 (according to Dimensions.get('window')).
So, when I run my app on Apple TV everything looks fine. But when I run it on an Android TV nothing fits on the screen.
Is there a way to force the Android TV to shrink everything? Or do I have to create two different style sheets for the different devices to change font sizes and dimensions of all my components?
We use a different approach, on the base Application class for tv we add this
class TvApplication extends Application {
#Override
protected void attachBaseContext(Context base) {
Configuration configuration = new Configuration(base.getResources().getConfiguration());
configuration.densityDpi = configuration.densityDpi / 2;
Context newContext = base.createConfigurationContext(configuration);
super.attachBaseContext(newContext);
}
}
with this, we have consistent width & height when using dimensions, and we can use the same styling values on all platforms without doing any manipulation on the JS side.
it's not perfect, but it's more convenient when building for multiple platforms
Use Platform.OS to check for platform and use margin property in styles to get the content right on screen in android. This is normal behavior in android tv.
You have PixelRatio and Dimensions for this purpose in React Native. Along with this you need to use a RN module react-native-pixel-perfect, this keeps your app pixel perfect across all devices, quickly and easily
import {PixelRatio, Dimensions} from 'react-native';
import {create} from 'react-native-pixel-perfect';
let displayProps = {
width: PixelRatio.roundToNearestPixel(
Dimensions.get('window').width * PixelRatio.get(),
),
height: PixelRatio.roundToNearestPixel(
Dimensions.get('window').height * PixelRatio.get(),
),
};
let perfectSize = create(displayProps);
Now always pass your size in pixels to this method to get original device pixels based on the devices.
const styles = StyleSheet.create({
container: {
width: perfectSize(500),
height: perfectSize(300)
}
});
Your container will adapt to the devices correctly. Based on their screen resolution.
In case if you have a minimum height x width to support but some devices are less than the minimum screen resolution and you want to still achieve the same results in those devices. Then you can set the minimum screen resolution on this function like below.
let displayProps = {
width: PixelRatio.roundToNearestPixel(
Math.max(1920, Dimensions.get('window').width * PixelRatio.get()),
),
height: PixelRatio.roundToNearestPixel(
Math.max(1080, Dimensions.get('window').height * PixelRatio.get()),
),
};
So in my case if the screen resolution is less than 1920x1080 lets say 720p devices then this will help rendering the UI in 1920x1080.

How to make React-Native "scrollTo" behave identically on Android than on iOS when ScrollView is small

Consider this simple ScrollView.
On iOS, clicking on the text will but the text to the top because scrollTo({ y: 250 }) scrolls even if end of scrollView is reached.
On Android, the text doesn't move.
How to get on Android the same behavior we have on iOS?
You can work around this by adding padding to the contentContainerStyle of the ScrollView. A good starting point would be to add padding equal to the height of the device's screen.
import { Dimensions } from 'react-native';
const ANDROID_SCREEN_HEIGHT_PADDING = Dimensions.get('window').height;
then, when rendering:
<ScrollView
contentContainerStyle={{paddingBottom: ANDROID_SCREEN_HEIGHT_PADDING}}>
...
</ScrollView>
You could use this for necessary extra Android padding in every direction. If you are using horizontal={true}, for example, you could add padding equal to the width of the screen and add it to the paddingLeft style property to get the intended scrolling behavior on Android.
This behavior is due to the underlying implementation of ScrollView on Android in React-Native. See also:
React native Android ScrollView scrollTo not working

How do you prevent over-scrolling using react-native ScrollView.scrollTo()?

After the user does some action I want to scroll to a particular section within a ScrollView, which I'm doing using this code:
this.refs.detailsView.measure((x, y, width, height, pageX, pageY) => {
this.refs.homeScrollView.scrollTo({ x: 0, y: pageY - 64, animated: true });
});
The problem is the "detailsView" View is near the bottom of the ScrollView and on the largest iPhones, scrollTo() ends up scrolling past the bottom of ScrollViews "natural" max scroll point and you can see the ScrollViews background colour (dary grey) as though you over-scrolled using touch gestures...the components in the ScrollView have the green background colour.
Does anyone have a suggestion for how to prevent this "over-scrolling" when using the ScrollView.scrollTo() function?
react-native: v0.36
This disables the scrollview from bouncing past its limit
bounces={false}

Splash screen fade-out in titanium

I want to fade out the splash screen.
I think it's possible in native code android or iOS.
However for titanium which way is the appropriate ??
for now my source code is this
var topWin = Ti.UI.createWindow();// main application window.
var img = Ti.UI.createImageView({
image : '/img/Default.png',
top : 0,
left : 0,
width : '100%',
height : '100%'
});
var splash = Ti.UI.createWindow(); //splash window
splash.add(img);
splash.open();
var fadeOut = Ti.UI.createAnimation({
opacity : 0.2,
duration : 300
});
var fadeIn = Ti.UI.createAnimation({
opacity : 1,
duration : 1800
});
setTimeout(function(e) {
splash.close(fadeOut);
topWin.open(fadeIn);
}, 3000);
It works as I mean however I think this way might be a bit strange.
Since
I have to decide the each image according to different resolution devices(iphone/ipad/android ,,) by manual while splash screen is chosen automatically.
Is there a good way other than this??
Take a look at this:
http://www.tidev.io/2015/01/06/how-to-re-use-the-launch-image-in-the-app/
I haven't done this in a while, and I'm not sure if the changes to 5.2 SDK for iOS for Storyboard launch files breaks this method but here's where I'd start.