[Android] Fit.Layout content stale after resize on the new backend (surface keeps creation size)
メンテナーはふだん 1 日以内に返信
評価
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 初心者へのやさしさ
- 25/100
調査の方向性
Start in android/src/new/java/com/rive/RiveReactNativeView.kt: compare onSurfaceTextureSizeChanged with resizeArtboardIfLayout, and check where the render surface is created in onSurfaceTextureAvailable and configure. Pull request #419 is already open against this issue, so review it before starting. Done means the layout_test.riv reproducer renders the same after a resize as after a remount.
索引モデルが issue の本文から書いたものです。
説明
Submission checklist
- I have confirmed the issue is present in the latest version of
@rive-app/react-native - I have searched the documentation and forums and could not find an answer
- I have searched existing issues and this is not a duplicate
Description
On the Android new (experimental) backend, resizing a mounted RiveView only resizes the artboard; the RiveSurface render target keeps the size it was created with. Content is then drawn into the old-size target, so it appears scaled and offset until the view is remounted. iOS resizes its drawable and is unaffected.
The code already notes the limitation:
RiveReactNativeView.kt#L150-L158—onSurfaceTextureSizeChangedupdatessurfaceWidth/Heightand callsresizeArtboardIfLayout(), with the comment "Since 11.7.x the render target keeps its creation-time size andRiveSurface.resize()is internal to the SDK, so only the artboard is resized here".RiveReactNativeView.kt#L328-L334—resizeArtboardIfLayoutresizes the artboard against the (stale-size) surface.- The surface is only ever created once, in
onSurfaceTextureAvailableandconfigure.
Common trigger: a Fit.Layout view mounts while a keyboard/numpad is animating in, so its container shrinks over the first ~300 ms. The view then renders too high / too small for the rest of its life.
Environment
@rive-app/react-native0.5.4, new backend (default); rive-android 11.12.1- Pixel 9 Pro emulator, API 36; React Native 0.86.3 (Fabric), Expo SDK 57
- iOS (rive-ios 6.28.0) does not reproduce
Notes
- App-side workaround: don't mount the view until its container has stopped resizing (e.g. gate on
onLayoutsettling), so the surface is created at the final size.
Related
- rive-app/rive-android#446 / rive-app/rive-android#450:
Fit.LAYOUTartboard size on the classicRiveAnimationView(one-shot resize flag). Same symptom family, different mechanism — here the artboard is resized; it's the render target that keeps its size.
Previous working version
0.4.20
Reproduction steps / code
Uses example/assets/rive/layout_test.riv. Toggle the container height, then remount at the same height — the two should look identical.
| step | container | surface created at | result |
|---|---|---|---|
| mount | 200 pt | 200 | rounded rect fills the view |
| animate to 400 pt | 400 | 200 (stale) | rect drawn clipped into the lower part of the view, offset right |
| remount at 400 pt | 400 | 400 | rect fills the view |
| animate back to 200 pt | 200 | 400 (stale) | rect drawn too high / too small |
| remount at 200 pt | 200 | 200 | same as first row |
Reproducer page (drop into example/src/reproducers/):
import { useCallback, useRef, useState } from 'react';
import { Animated, Pressable, Text, View, StyleSheet } from 'react-native';
import { Fit, RiveView, useRiveFile } from '@rive-app/react-native';
const SHORT = 200;
const TALL = 400;
export default function ReproSurfaceSize() {
const { riveFile } = useRiveFile(require('../../assets/rive/layout_test.riv'));
const [height] = useState(() => new Animated.Value(SHORT));
const tall = useRef(false);
const [generation, setGeneration] = useState(0);
const toggle = useCallback(() => {
tall.current = !tall.current;
Animated.timing(height, { toValue: tall.current ? TALL : SHORT, duration: 400, useNativeDriver: false }).start();
}, [height]);
return (
<View style={styles.container}>
<Pressable style={styles.button} onPress={toggle}><Text style={styles.buttonText}>Toggle height</Text></Pressable>
<Pressable style={styles.button} onPress={() => setGeneration((g) => g + 1)}><Text style={styles.buttonText}>Remount</Text></Pressable>
<Animated.View style={[styles.box, { height }]}>
{riveFile ? <RiveView key={generation} file={riveFile} fit={Fit.Layout} autoPlay style={styles.rive} /> : null}
</Animated.View>
</View>
);
}
const styles = StyleSheet.create({
container: { flex: 1, padding: 16, backgroundColor: '#fff' },
box: { marginTop: 16, backgroundColor: '#1a2a3a' },
rive: { flex: 1 },
button: { alignSelf: 'flex-start', backgroundColor: '#007AFF', paddingHorizontal: 20, paddingVertical: 10, borderRadius: 8, marginTop: 8 },
buttonText: { color: '#fff', fontWeight: '600' },
});
Upload your reproduction files / stack trace
No response
Source .riv / .rev file
No response
Screenshots / video
No response
@rive-app/react-native version
0.5.4
Platform
Android only
React Native version
0.86.3
React Native environment info
Expo setup
Yes — Expo prebuild / EAS Build
Expo SDK version (if applicable)
57
iOS device & OS version (if applicable)
No response
Android device & OS version (if applicable)
Pixel 9 Pro emulator, API 36
Additional context
No response
- 主要言語
- TypeScript
- スター
- 157
- フォーク
- 16
- 平均マージ
- 1日 7時間
- マージ済み PR(30日)
- 16
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
rive-app/rive-nitro-react-native のほかの issue
-
難易度 4/5 3〜5日 初心者へのやさしさ 35/100
rive-app/rive-nitro-react-native#424 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
Rive drains battery in the background on Android対応中かも @mfazekas が 18 日前に担当しました。 オープンandroid bug
難易度 4/5 3〜5日 初心者へのやさしさ 48/100
rive-app/rive-nitro-react-native#413 ·
メンテナーはふだん 1 日以内に返信
-
[Android] RiveFonts: loadFont({name}) fails for script fonts on OEM fonts.xml; systemFallback() is not script-aware (tofu for Thai/Hebrew/Arabic/CJK)対応中かも @mfazekas が 26 日前に担当しました。 オープンandroid bug
難易度 3/5 1〜2日 初心者へのやさしさ 65/100
rive-app/rive-nitro-react-native#369 · コメント 3 件 ·
メンテナーはふだん 1 日以内に返信
-
enhancement iOS
難易度 4/5 3〜5日 初心者へのやさしさ 35/100
rive-app/rive-nitro-react-native#58 · コメント 7 件 ·
メンテナーはふだん 1 日以内に返信
rive-app/rive-nitro-react-native の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
gnosis/gnosis_vpn#661 ·
メンテナーはふだん 1 日以内に返信
-
content-freshness: staleOwnedContent doc comments still say 'complete receipt' (follow-up to #7912)オープンtriage:bug-verified
難易度 1/5 1時間未満 初心者へのやさしさ 92/100
メンテナーはふだん 1 日以内に返信
-
fix: reject sourceStorage/packagedStorage bucket that differs from the stack default (fail loud)オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
Eyevinn/open-videocore#1300 ·
メンテナーはふだん 1 日以内に返信
-
nextjs-tracking
難易度 2/5 1〜3時間 初心者へのやさしさ 67/100
cloudflare/vinext#4390 ·
メンテナーはふだん 1 日以内に返信
-
kind/bug
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
kubernetes-sigs/headlamp#8175 ·
メンテナーはふだん 2 日以内に返信