React Native
프로젝트를 진행하면서 모바일 디바이스의 폰트 크기 설정으로 인해 앱 디자인이 이상해지는 문제가 발생했다. 모바일 앱 특성상 사용자의 폰트 크기 설정에 영향을 받을 수 밖에 없는데, 이를 막는 것은 매우 좋지 않은 해결방법이다. 하지만 프로젝트 기간 안에 앱의 디자인이 깨져버리는 것을 수정해야 했고, 이 원인의 해결방안으로 우선 모바일의 시스템 폰트 크기 설정에 대해 영향을 안 받도록 수정하는 것이였다.
여러 라이브러리를 적용하면 반응형으로 폰트 크기를 설정할 수 있지만, 단순히 앱에서 적용된 폰트 크기대로 설정해주면 되는 문제라 우선 시스템 폰트 크기 설정만 영향을 받지 않도록 수정하는 방향대로 가기로 하였다.
여러 구글링을 거쳐 온 결과 아래의 방법대로 코드를 적용하면 안드로이드와 아이폰에서 시스템 폰트 크기를 설정에 대한 영향을 막을 수 있다.
android/app/src/main/java/[패키지경로]
의 MainApplication.java
에서 다음과 같이 추가한다.// 패키지 임포트
import android.view.WindowManager;
import android.content.res.Configuration;
import android.content.Context;
import android.util.DisplayMetrics;
// onCreate메서드에서 super.onCreate()구문 밑에 추가
adjustFontScale(getApplicationContext(),getResources().getConfiguration());
// onCreate메서드 밑에 추가
public void adjustFontScale(Context context, Configuration configuration) {
if (configuration.fontScale != 1) {
configuration.fontScale = 1;
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
wm.getDefaultDisplay().getMetrics(metrics);
metrics.scaledDensity = configuration.fontScale * metrics.density;
context.getResources().updateConfiguration(configuration, metrics);
}
}
package com.reactnativetest;
import android.app.Application;
import com.facebook.react.PackageList;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
import com.facebook.react.defaults.DefaultReactNativeHost;
import com.facebook.soloader.SoLoader;
import java.util.List;
// 패키지 임포트
import android.view.WindowManager;
import android.content.res.Configuration;
import android.content.Context;
import android.util.DisplayMetrics;
public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost =
new DefaultReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
@SuppressWarnings("UnnecessaryLocalVariable")
List<ReactPackage> packages = new PackageList(this).getPackages();
// Packages that cannot be autolinked yet can be added manually here, for example:
// packages.add(new MyReactNativePackage());
return packages;
}
@Override
protected String getJSMainModuleName() {
return "index";
}
@Override
protected boolean isNewArchEnabled() {
return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
}
@Override
protected Boolean isHermesEnabled() {
return BuildConfig.IS_HERMES_ENABLED;
}
};
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
@Override
public void onCreate() {
super.onCreate();
adjustFontScale(getApplicationContext(),getResources().getConfiguration()); // 추가
SoLoader.init(this, /* native exopackage */ false);
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
// If you opted-in for the New Architecture, we load the native entry point for this app.
DefaultNewArchitectureEntryPoint.load();
}
ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
}
// 추가
public void adjustFontScale(Context context, Configuration configuration) {
if (configuration.fontScale != 1) {
configuration.fontScale = 1;
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
wm.getDefaultDisplay().getMetrics(metrics);
metrics.scaledDensity = configuration.fontScale * metrics.density;
context.getResources().updateConfiguration(configuration, metrics);
}
}
}
import { Text, TextInput } from "react-native";
if (Text.defaultProps == null) {
Text.defaultProps = {};
Text.defaultProps.allowFontScaling = false;
TextInput.defaultProps = TextInput.defaultProps || {};
TextInput.defaultProps.allowFontScaling = false;
}
import {AppRegistry, Text, TextInput} from 'react-native';
import App from './App';
import {name as appName} from './app.json';
AppRegistry.registerComponent(appName, () => App);
if (Text.defaultProps == null) {
Text.defaultProps = {};
Text.defaultProps.allowFontScaling = false;
TextInput.defaultProps = TextInput.defaultProps || {};
TextInput.defaultProps.allowFontScaling = false;
}