Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

[Android] Fit.Layout content stale after resize on the new backend (surface keeps creation size)

オープン
#418 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

@mfazekas がすでに取り組んでいます。

2026年10月13日 から。

  • #419 @mfazekas による — オープン

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
25/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
停滞
技術スタック
android, kotlin, react-native
領域
mobile

調査の方向性

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 — onSurfaceTextureSizeChanged updates surfaceWidth/Height and calls resizeArtboardIfLayout(), with the comment "Since 11.7.x the render target keeps its creation-time size and RiveSurface.resize() is internal to the SDK, so only the artboard is resized here".
  • RiveReactNativeView.kt#L328-L334 — resizeArtboardIfLayout resizes the artboard against the (stale-size) surface.
  • The surface is only ever created once, in onSurfaceTextureAvailable and configure.

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-native 0.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 onLayout settling), so the surface is created at the final size.
Related
  • rive-app/rive-android#446 / rive-app/rive-android#450: Fit.LAYOUT artboard size on the classic RiveAnimationView (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

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

rive-app/rive-nitro-react-native のほかの issue

rive-app/rive-nitro-react-native の issue をすべて見る

似ている issue

TypeScript の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。