BREAKING: Android: Correct value of Dimensions.get('screen').fontScale
Summary: The PR description has been updated to reflect the new approach. **Breaking Change Summary** On Android, the following properties now return a different number: - `Dimensions.get('window').fontScale` - `Dimensions.get('screen').fontScale` - `PixelRatio.getFontScale()` This is a breaking change to anyone who was using these properties because the meaning of these properties has now changed. These properties used to return a value representing font scale times density ([`DisplayMetrics.scaledDensity`](https://developer.android.com/reference/android/util/DisplayMetrics.html#scaledDensity)). Now they return a value representing just font scale ([`Configuration.fontScale`](https://developer.android.com/reference/android/content/res/Configuration.html#fontScale)). **PR Description** This PR changes a few things: - Correctly exposes the font scale to JavaScript as `Dimensions.get('screen').fontScale`. UIManager was exporting `DisplayMetrics.scaledDensity` under the name `fontScale`. How Closes https://github.com/facebook/react-native/pull/11008 Differential Revision: D4558207 Pulled By: astreet fbshipit-source-id: 096ce7b28051325dfd45fdb2a14b5e9b7d3bc46f
This commit is contained in:
parent
7f9876c049
commit
186f308aec
|
@ -11,12 +11,15 @@
|
|||
*/
|
||||
'use strict';
|
||||
|
||||
var EventEmitter = require('EventEmitter');
|
||||
var Platform = require('Platform');
|
||||
var UIManager = require('UIManager');
|
||||
var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');
|
||||
|
||||
var invariant = require('fbjs/lib/invariant');
|
||||
|
||||
var eventEmitter = new EventEmitter();
|
||||
var dimensionsInitialized = false;
|
||||
var dimensions = {};
|
||||
class Dimensions {
|
||||
/**
|
||||
|
@ -60,6 +63,15 @@ class Dimensions {
|
|||
}
|
||||
|
||||
Object.assign(dimensions, dims);
|
||||
if (dimensionsInitialized) {
|
||||
// Don't fire 'change' the first time the dimensions are set.
|
||||
eventEmitter.emit('change', {
|
||||
window: dimensions.window,
|
||||
screen: dimensions.screen
|
||||
});
|
||||
} else {
|
||||
dimensionsInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -81,6 +93,39 @@ class Dimensions {
|
|||
invariant(dimensions[dim], 'No dimension set for key ' + dim);
|
||||
return dimensions[dim];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an event handler. Supported events:
|
||||
*
|
||||
* - `change`: Fires when a property within the `Dimensions` object changes. The argument
|
||||
* to the event handler is an object with `window` and `screen` properties whose values
|
||||
* are the same as the return values of `Dimensions.get('window')` and
|
||||
* `Dimensions.get('screen')`, respectively.
|
||||
*/
|
||||
static addEventListener(
|
||||
type: string,
|
||||
handler: Function
|
||||
) {
|
||||
invariant(
|
||||
'change' === type,
|
||||
'Trying to subscribe to unknown event: "%s"', type
|
||||
);
|
||||
eventEmitter.addListener(type, handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an event handler.
|
||||
*/
|
||||
static removeEventListener(
|
||||
type: string,
|
||||
handler: Function
|
||||
) {
|
||||
invariant(
|
||||
'change' === type,
|
||||
'Trying to remove listener for unknown event: "%s"', type
|
||||
);
|
||||
eventEmitter.removeListener(type, handler);
|
||||
}
|
||||
}
|
||||
|
||||
Dimensions.set(UIManager.Dimensions);
|
||||
|
|
|
@ -394,27 +394,10 @@ public class ReactRootView extends SizeMonitoringFrameLayout implements RootView
|
|||
}
|
||||
|
||||
private void emitUpdateDimensionsEvent() {
|
||||
DisplayMetrics windowDisplayMetrics = DisplayMetricsHolder.getWindowDisplayMetrics();
|
||||
DisplayMetrics screenDisplayMetrics = DisplayMetricsHolder.getScreenDisplayMetrics();
|
||||
|
||||
WritableMap windowDisplayMetricsMap = Arguments.createMap();
|
||||
windowDisplayMetricsMap.putInt("width", windowDisplayMetrics.widthPixels);
|
||||
windowDisplayMetricsMap.putInt("height", windowDisplayMetrics.heightPixels);
|
||||
windowDisplayMetricsMap.putDouble("scale", windowDisplayMetrics.density);
|
||||
windowDisplayMetricsMap.putDouble("fontScale", windowDisplayMetrics.scaledDensity);
|
||||
windowDisplayMetricsMap.putDouble("densityDpi", windowDisplayMetrics.densityDpi);
|
||||
|
||||
WritableMap screenDisplayMetricsMap = Arguments.createMap();
|
||||
screenDisplayMetricsMap.putInt("width", screenDisplayMetrics.widthPixels);
|
||||
screenDisplayMetricsMap.putInt("height", screenDisplayMetrics.heightPixels);
|
||||
screenDisplayMetricsMap.putDouble("scale", screenDisplayMetrics.density);
|
||||
screenDisplayMetricsMap.putDouble("fontScale", screenDisplayMetrics.scaledDensity);
|
||||
screenDisplayMetricsMap.putDouble("densityDpi", screenDisplayMetrics.densityDpi);
|
||||
|
||||
WritableMap dimensionsMap = Arguments.createMap();
|
||||
dimensionsMap.putMap("windowPhysicalPixels", windowDisplayMetricsMap);
|
||||
dimensionsMap.putMap("screenPhysicalPixels", screenDisplayMetricsMap);
|
||||
sendEvent("didUpdateDimensions", dimensionsMap);
|
||||
mReactInstanceManager
|
||||
.getCurrentReactContext()
|
||||
.getNativeModule(UIManagerModule.class)
|
||||
.emitUpdateDimensionsEvent();
|
||||
}
|
||||
|
||||
private void sendEvent(String eventName, @Nullable WritableMap params) {
|
||||
|
|
|
@ -32,8 +32,10 @@ import com.facebook.react.bridge.ReactMarker;
|
|||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.common.ReactConstants;
|
||||
import com.facebook.react.module.annotations.ReactModule;
|
||||
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
||||
import com.facebook.react.uimanager.debug.NotThreadSafeViewHierarchyUpdateDebugListener;
|
||||
import com.facebook.react.uimanager.events.EventDispatcher;
|
||||
import com.facebook.systrace.Systrace;
|
||||
|
@ -88,6 +90,7 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements
|
|||
private final Map<String, Object> mModuleConstants;
|
||||
private final UIImplementation mUIImplementation;
|
||||
private final MemoryTrimCallback mMemoryTrimCallback = new MemoryTrimCallback();
|
||||
private float mFontScale;
|
||||
|
||||
private int mNextRootViewTag = 1;
|
||||
private int mBatchId = 0;
|
||||
|
@ -100,7 +103,8 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements
|
|||
super(reactContext);
|
||||
DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(reactContext);
|
||||
mEventDispatcher = new EventDispatcher(reactContext);
|
||||
mModuleConstants = createConstants(viewManagerList, lazyViewManagersEnabled);
|
||||
mFontScale = getReactApplicationContext().getResources().getConfiguration().fontScale;
|
||||
mModuleConstants = createConstants(viewManagerList, lazyViewManagersEnabled, mFontScale);
|
||||
mUIImplementation = uiImplementationProvider
|
||||
.createUIImplementation(reactContext, viewManagerList, mEventDispatcher);
|
||||
|
||||
|
@ -133,6 +137,12 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements
|
|||
@Override
|
||||
public void onHostResume() {
|
||||
mUIImplementation.onHostResume();
|
||||
|
||||
float fontScale = getReactApplicationContext().getResources().getConfiguration().fontScale;
|
||||
if (mFontScale != fontScale) {
|
||||
mFontScale = fontScale;
|
||||
emitUpdateDimensionsEvent();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -156,13 +166,15 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements
|
|||
|
||||
private static Map<String, Object> createConstants(
|
||||
List<ViewManager> viewManagerList,
|
||||
boolean lazyViewManagersEnabled) {
|
||||
boolean lazyViewManagersEnabled,
|
||||
float fontScale) {
|
||||
ReactMarker.logMarker(CREATE_UI_MANAGER_MODULE_CONSTANTS_START);
|
||||
Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "CreateUIManagerConstants");
|
||||
try {
|
||||
return UIManagerModuleConstantsHelper.createConstants(
|
||||
viewManagerList,
|
||||
lazyViewManagersEnabled);
|
||||
lazyViewManagersEnabled,
|
||||
fontScale);
|
||||
} finally {
|
||||
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
|
||||
ReactMarker.logMarker(CREATE_UI_MANAGER_MODULE_CONSTANTS_END);
|
||||
|
@ -541,6 +553,16 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements
|
|||
mUIImplementation.sendAccessibilityEvent(tag, eventType);
|
||||
}
|
||||
|
||||
public void emitUpdateDimensionsEvent() {
|
||||
sendEvent("didUpdateDimensions", UIManagerModuleConstants.getDimensionsConstants(mFontScale));
|
||||
}
|
||||
|
||||
private void sendEvent(String eventName, @Nullable WritableMap params) {
|
||||
getReactApplicationContext()
|
||||
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
|
||||
.emit(eventName, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule a block to be executed on the UI thread. Useful if you need to execute
|
||||
* view logic after all currently queued view updates have completed.
|
||||
|
|
|
@ -16,6 +16,8 @@ import android.util.DisplayMetrics;
|
|||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.common.MapBuilder;
|
||||
import com.facebook.react.uimanager.events.TouchEventType;
|
||||
|
||||
|
@ -81,7 +83,7 @@ import com.facebook.react.uimanager.events.TouchEventType;
|
|||
.build();
|
||||
}
|
||||
|
||||
public static Map<String, Object> getConstants() {
|
||||
public static Map<String, Object> getConstants(float fontScale) {
|
||||
HashMap<String, Object> constants = new HashMap<String, Object>();
|
||||
constants.put(
|
||||
"UIView",
|
||||
|
@ -95,35 +97,9 @@ import com.facebook.react.uimanager.events.TouchEventType;
|
|||
"ScaleAspectCenter",
|
||||
ImageView.ScaleType.CENTER_INSIDE.ordinal())));
|
||||
|
||||
DisplayMetrics displayMetrics = DisplayMetricsHolder.getWindowDisplayMetrics();
|
||||
DisplayMetrics screenDisplayMetrics = DisplayMetricsHolder.getScreenDisplayMetrics();
|
||||
constants.put(
|
||||
"Dimensions",
|
||||
MapBuilder.of(
|
||||
"windowPhysicalPixels",
|
||||
MapBuilder.of(
|
||||
"width",
|
||||
displayMetrics.widthPixels,
|
||||
"height",
|
||||
displayMetrics.heightPixels,
|
||||
"scale",
|
||||
displayMetrics.density,
|
||||
"fontScale",
|
||||
displayMetrics.scaledDensity,
|
||||
"densityDpi",
|
||||
displayMetrics.densityDpi),
|
||||
"screenPhysicalPixels",
|
||||
MapBuilder.of(
|
||||
"width",
|
||||
screenDisplayMetrics.widthPixels,
|
||||
"height",
|
||||
screenDisplayMetrics.heightPixels,
|
||||
"scale",
|
||||
screenDisplayMetrics.density,
|
||||
"fontScale",
|
||||
screenDisplayMetrics.scaledDensity,
|
||||
"densityDpi",
|
||||
screenDisplayMetrics.densityDpi)));
|
||||
getDimensionsConstants(fontScale));
|
||||
|
||||
constants.put(
|
||||
"StyleConstants",
|
||||
|
@ -157,4 +133,29 @@ import com.facebook.react.uimanager.events.TouchEventType;
|
|||
|
||||
return constants;
|
||||
}
|
||||
|
||||
public static WritableMap getDimensionsConstants(float fontScale) {
|
||||
DisplayMetrics windowDisplayMetrics = DisplayMetricsHolder.getWindowDisplayMetrics();
|
||||
DisplayMetrics screenDisplayMetrics = DisplayMetricsHolder.getScreenDisplayMetrics();
|
||||
|
||||
WritableMap windowDisplayMetricsMap = Arguments.createMap();
|
||||
windowDisplayMetricsMap.putInt("width", windowDisplayMetrics.widthPixels);
|
||||
windowDisplayMetricsMap.putInt("height", windowDisplayMetrics.heightPixels);
|
||||
windowDisplayMetricsMap.putDouble("scale", windowDisplayMetrics.density);
|
||||
windowDisplayMetricsMap.putDouble("fontScale", fontScale);
|
||||
windowDisplayMetricsMap.putDouble("densityDpi", windowDisplayMetrics.densityDpi);
|
||||
|
||||
WritableMap screenDisplayMetricsMap = Arguments.createMap();
|
||||
screenDisplayMetricsMap.putInt("width", screenDisplayMetrics.widthPixels);
|
||||
screenDisplayMetricsMap.putInt("height", screenDisplayMetrics.heightPixels);
|
||||
screenDisplayMetricsMap.putDouble("scale", screenDisplayMetrics.density);
|
||||
screenDisplayMetricsMap.putDouble("fontScale", fontScale);
|
||||
screenDisplayMetricsMap.putDouble("densityDpi", screenDisplayMetrics.densityDpi);
|
||||
|
||||
WritableMap dimensionsMap = Arguments.createMap();
|
||||
dimensionsMap.putMap("windowPhysicalPixels", windowDisplayMetricsMap);
|
||||
dimensionsMap.putMap("screenPhysicalPixels", screenDisplayMetricsMap);
|
||||
|
||||
return dimensionsMap;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ package com.facebook.react.uimanager;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.common.MapBuilder;
|
||||
import com.facebook.systrace.Systrace;
|
||||
import com.facebook.systrace.SystraceMessage;
|
||||
|
@ -42,8 +43,9 @@ import static com.facebook.systrace.Systrace.TRACE_TAG_REACT_JAVA_BRIDGE;
|
|||
*/
|
||||
/* package */ static Map<String, Object> createConstants(
|
||||
List<ViewManager> viewManagers,
|
||||
boolean lazyViewManagersEnabled) {
|
||||
Map<String, Object> constants = UIManagerModuleConstants.getConstants();
|
||||
boolean lazyViewManagersEnabled,
|
||||
float fontScale) {
|
||||
Map<String, Object> constants = UIManagerModuleConstants.getConstants(fontScale);
|
||||
Map bubblingEventTypesConstants = UIManagerModuleConstants.getBubblingEventTypeConstants();
|
||||
Map directEventTypesConstants = UIManagerModuleConstants.getDirectEventTypeConstants();
|
||||
|
||||
|
|
Loading…
Reference in New Issue