-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Android] measure
giving incorrect values
#3188
Comments
Running into the same issue. Have you managed to patch this up somehow or did you end up having to use another method for grabbing |
Unfortunately I did not find a good way around this, and we ended up changing the design. |
##Update ##Original Packages Info
Logs on my end: |
Hello @256hz! Thanks for reporting the problem. Unfortunately, I wasn't able to reproduce this issue on Also, I've needed to modify a few lines in the provided code snippets, e.g. change App.tsximport React, { useEffect } from 'react';
import Animated, {
measure,
useAnimatedRef,
useAnimatedStyle,
useDerivedValue,
useSharedValue,
withTiming,
} from 'react-native-reanimated';
import { ReText } from 'react-native-redash';
export default function App() {
const textContainer = useAnimatedRef<Animated.View>();
const textValue = useSharedValue(0);
const textPadding = useSharedValue(0);
const animatedText = useDerivedValue(() => textValue.value.toFixed(2));
const containerStyle = useAnimatedStyle(() => ({
paddingLeft: textPadding.value,
}));
useEffect(() => {
textValue.value = withTiming(100, { duration: 2000 }, () => {
'worklet';
const measured = measure(textContainer);
console.log(measured);
textPadding.value = withTiming(measured.width);
});
}, []);
return (
<Animated.View ref={textContainer} style={containerStyle}>
<ReText text={animatedText} />
</Animated.View>
);
} Here are the logs from iOS simulator:
And here are the logs from Android emulator:
🐛 ReproductionThe good news is that I was able to successfully reproduce the issue on the example provided by @boxedition. Here are the logs from Android emulator:
❓ ExplanationIn the old architecture (Paper), React Native on Android uses an optimization technique called view flattening which skips unnecessary views which don't affect the app visually when mounting the component tree. Most likely these views have been flattened so they don't exist in the native tree hierarchy. In such case,
However, in react-native-reanimated/android/src/main/java/com/swmansion/reanimated/NodesManager.java Lines 53 to 62 in b782d1a
Next, in react-native-reanimated/android/src/main/cpp/NativeProxy.cpp Lines 421 to 439 in 730e3b5
Since the array has length of zero, we get non-deterministic values when reading its elements. Additionally, adding From the perspective of Reanimated, a proper solution would be to throw an error and propagate it to JS or return ✅ SolutionHowever, after changing Ripple.tsximport React from 'react';
import { StyleProp, StyleSheet, View, ViewStyle } from 'react-native';
import { TapGestureHandler, TapGestureHandlerGestureEvent } from 'react-native-gesture-handler';
import Animated, {
measure,
runOnJS,
useAnimatedGestureHandler,
useAnimatedRef,
useAnimatedStyle,
useSharedValue,
withTiming
} from 'react-native-reanimated';
interface IRippleProps {
style?: StyleProp<ViewStyle>,
onTap?: () => void,
}
const Ripple: React.FC<IRippleProps> = ({ style, onTap, children }) => {
const aRef = useAnimatedRef<Animated.View>()
const centerX = useSharedValue(0)
const centerY = useSharedValue(0)
const scale = useSharedValue(0)
//const width = useSharedValue(0)
//const height = useSharedValue(0)
const tapGestureEvent = useAnimatedGestureHandler<TapGestureHandlerGestureEvent>({
onStart(event, context) {
const layout = measure(aRef)
console.log(layout)
//width.value = layout.width
//height.value = layout.height
centerX.value = event.x
centerY.value = event.y
scale.value = 0
scale.value = withTiming(1, { duration: 450 })
},
onActive(event, context) {
if (onTap) {
runOnJS(onTap)()
}
},
onEnd(event, context) {
},
})
const rStyle = useAnimatedStyle(() => {
//const circleRadius = Math.sqrt(width.value ** 2 + height.value ** 2)
const circleRadius = 500
const translateX = centerX.value - circleRadius
const translateY = centerY.value - circleRadius
return {
position: 'absolute',
backgroundColor: 'red',
width: circleRadius * 2,
height: circleRadius * 2,
borderRadius: circleRadius,
top: 0,
left: 0,
transform: [
{ translateX },
{ translateY },
{ scale: scale.value },
],
opacity: 0.2,
}
})
return (
<Animated.View ref={aRef}>
<TapGestureHandler onGestureEvent={tapGestureEvent}>
<Animated.View style={[style, { overflow: 'hidden' }]}>
<View style={style}>{children}</View>
<Animated.View style={[rStyle]} />
</Animated.View>
</TapGestureHandler>
</Animated.View>
)
};
export default Ripple; Also, it works fine when I change Here are the logs from iOS:
Here are the logs from Android:
💡 ConclusionIf you want to use |
@tomekzaw setting collapsable={false} does not fix the issue on android. i am always getting 0 for value of x |
i face the same issue, always 0 for x and y |
I face the same issue. If you are using the ref's current?.measure method, it is recommended to use onLayout instead. But if you use pageX and pageY, there seems to be no way yet. |
@longb1997 Looks like this might have been fixed with #6413. |
was this released ? Ok I found the release (3.16.0) but I still have the case of measure giving values (height and width are 0 and pageX is wrong value) |
Description
I'm using
measure
with an animated ref. On iOS, this works as expected and outputs the right values. On Android, the values are (as far as I can tell) unrelated to the component's size, and seem to change over time.Expected behavior
I'm animating some text using ReText, and using the final size of that text in a padding animation. So, at the end of the ReText change, I measure the view that's around the text, and set some padding based on that. The measure step is where the below console logs come from.
Steps to Reproduce includes a minimal example with more context.
Output of
console.log(measured)
on iOS:This is great and gives me exactly what I need.
Actual behavior
Output of
console.log(measured)
on Android:These values aren't stable. For example if I run this again directly afterward (this is after the ReText has stopped resizing), I get:
These values are less helpful.
Snack or minimal code example
Simplified version of my implementation below.
Package versions
Affected platforms
The text was updated successfully, but these errors were encountered: