always set camera distance on transforms, to default 1280 if 0

Summary:
This is the better fix for the same issue as mentioned in PR https://github.com/facebook/react-native/pull/14560

Certain rotateX, rotateY, scaleX and scaleY animations do not work correctly on some phones in Android 7.0.0, causing issues such as https://github.com/facebook/react-native/issues/14462 and https://github.com/facebook/react-native/issues/13522.

The issue can be fixed on JS side by setting an additional transform for perspective, eg. `{perspective: 1}` which triggers a `setCameraDistance` call in native code.

The fix in this PR always sets the camera distance on transforms, even when no perspective transform was specified. The default camera distance is set before the scale multiplication, to make sure that the value is appropriate for the phones density. The value calculates to an Android 'default' camera distance of 1280 * scale multiplier; https://developer.android.com/reference/android/view/View.html#setCameraDistance(float)

If a perspective transform is specified, this value will be used correctly still.

This fix was tested on the RNTester. Before the fix, on some devices, the FlatList example, with inverted turned on, will not display the list.

Devices that have been confirmed to have this issue:
FRD-AL10(honor 8) EMUI:5.0 android: 7.0
MHA-AL00(Mate9) EMUI:5.0 android:7.0
Huawei P10 VTR-L09, running Android 7.0

After the fix, the inverted FlatList displays correctly.
Closes https://github.com/facebook/react-native/pull/14646

Differential Revision: D5492009

Pulled By: shergin

fbshipit-source-id: d4da3b090a7e65df3b84e48ea32c964f4f8f7c88
This commit is contained in:
Bartol Karuza 2017-08-06 19:12:02 -07:00 committed by Facebook Github Bot
parent c5bd033e4b
commit b2fe048a0b
1 changed files with 11 additions and 9 deletions

View File

@ -184,16 +184,18 @@ public abstract class BaseViewManager<T extends View, C extends LayoutShadowNode
if (perspectiveArray.length > PERSPECTIVE_ARRAY_INVERTED_CAMERA_DISTANCE_INDEX) {
float invertedCameraDistance = (float) perspectiveArray[PERSPECTIVE_ARRAY_INVERTED_CAMERA_DISTANCE_INDEX];
if (invertedCameraDistance < 0) {
float cameraDistance = -1 / invertedCameraDistance;
float scale = DisplayMetricsHolder.getScreenDisplayMetrics().density;
// The following converts the matrix's perspective to a camera distance
// such that the camera perspective looks the same on Android and iOS
float normalizedCameraDistance = scale * cameraDistance * CAMERA_DISTANCE_NORMALIZATION_MULTIPLIER;
view.setCameraDistance(normalizedCameraDistance);
if (invertedCameraDistance == 0) {
// Default camera distance, before scale multiplier (1280)
invertedCameraDistance = 0.00078125f;
}
float cameraDistance = -1 / invertedCameraDistance;
float scale = DisplayMetricsHolder.getScreenDisplayMetrics().density;
// The following converts the matrix's perspective to a camera distance
// such that the camera perspective looks the same on Android and iOS
float normalizedCameraDistance = scale * cameraDistance * CAMERA_DISTANCE_NORMALIZATION_MULTIPLIER;
view.setCameraDistance(normalizedCameraDistance);
}
}