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

Viewed 1133

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?

3 Answers

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.

Related