flutter 当Transform.scale包裹opacity时,重复缩放动画不起作用,

nzkunb0c  于 6个月前  发布在  Flutter
关注(0)|答案(2)|浏览(47)

重现步骤

  1. 使用Flutter beta
  2. 粘贴代码
  3. 点击正方形,动画按预期工作
  4. 再次点击正方形,缩放不起作用,只有透明度起作用。

预期结果

缩放动画在后续的动画调用中应该起作用,而不仅仅是第一次。

实际结果

当缩放动画被多次调用时,它不起作用,而透明度动画可以。经过热重载后,只渲染缩放动画的最后一帧。有趣的是,如果我们用Transform.scale小部件替换Opacity小部件,一切都按预期工作(当Opacity包裹Transform.scale时,而不是Transform.scale包裹Opacity)。

代码示例

代码示例

class TestAnimation extends StatefulWidget {
  const TestAnimation({super.key});

  @override
  State<TestAnimation> createState() => _TestAnimationState();
}

class _TestAnimationState extends State<TestAnimation>
    with SingleTickerProviderStateMixin {
  late final AnimationController _controller;

  Animation<double> _scale = const AlwaysStoppedAnimation(0);
  Animation<double> _opacity = const AlwaysStoppedAnimation(0);

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 2),
    );
    _controller.addListener(() => setState(() {}));
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  TickerFuture _animate() {
    _scale = _controller.drive(
      Tween<double>(
        begin: 0,
        end: 1.5,
      ),
    );

    _opacity = _controller.drive(
      Tween<double>(
        begin: 0,
        end: 1,
      ),
    );

    return _controller.forward(from: 0);
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      behavior: HitTestBehavior.translucent,
      onTap: _animate,
      child: DecoratedBox(
        decoration: BoxDecoration(
          border: Border.all(
            width: 2,
            color: Colors.green,
          ),
        ),
        child: Transform.scale(
          scale: _scale.value,
          child: Opacity(
            opacity: _opacity.value,
            child: Container(
              width: 50,
              height: 50,
              color: Colors.red,
            ),
          ),
        ),
      ),
    );
  }
}

截图或视频

截图/视频演示Screen.Recording.2024-07-14.at.4.27.32.PM.mov

日志

日志

[Paste your logs here]

Flutter Doctor输出

Doctor输出

Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel beta, 3.23.0-0.1.pre, on macOS 14.5 23F79 darwin-arm64,
locale en-US)
[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 15.4)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2022.3)
[✓] VS Code (version 1.90.2)
[✓] Connected device (5 available)
[✓] Network resources

• No issues found!
ego6inou

ego6inou1#

可复现性:使用上述提供的代码示例
完整代码示例

import 'package:flutter/material.dart';

/// Flutter code sample for [Autocomplete].

void main() => runApp(const AutocompleteExampleApp());

class AutocompleteExampleApp extends StatelessWidget {
  const AutocompleteExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: TestAnimation(),
    );
  }
}

class TestAnimation extends StatefulWidget {
  const TestAnimation({super.key});

  @override
  State<TestAnimation> createState() => _TestAnimationState();
}

class _TestAnimationState extends State<TestAnimation>
    with SingleTickerProviderStateMixin {
  late final AnimationController _controller;

  Animation<double> _scale = const AlwaysStoppedAnimation(0);
  Animation<double> _opacity = const AlwaysStoppedAnimation(0);

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 2),
    );
    _controller.addListener(() => setState(() {}));
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  TickerFuture _animate() {
    _scale = _controller.drive(
      Tween<double>(
        begin: 0,
        end: 1.5,
      ),
    );

    _opacity = _controller.drive(
      Tween<double>(
        begin: 0,
        end: 1,
      ),
    );

    return _controller.forward(from: 0);
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      behavior: HitTestBehavior.translucent,
      onTap: _animate,
      child: Center(
        child: SizedBox(
          height: 100,
          width: 100,
          child: DecoratedBox(
            decoration: BoxDecoration(
              border: Border.all(
                width: 2,
                color: Colors.green,
              ),
            ),
            child: Transform.scale(
              scale: _scale.value,
              child: Opacity(
                opacity: _opacity.value,
                child: Container(
                  width: 50,
                  height: 50,
                  color: Colors.red,
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

flutter doctor -v

[✓] Flutter (Channel stable, 3.22.2, on macOS 14.4.1 23E224 darwin-arm64, locale en-GB)
    • Flutter version 3.22.2 on channel stable at /Users/nexus/dev/sdks/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 761747bfc5 (6 weeks ago), 2024-06-05 22:15:13 +0200
    • Engine revision edd8546116
    • Dart version 3.4.3
    • DevTools version 2.34.3

[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
    • Android SDK at /Users/nexus/Library/Android/sdk
    • Platform android-34, build-tools 34.0.0
    • Java binary at: /Users/nexus/Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 17.0.10+0-17.0.10b1087.21-11609105)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 15.3)
    • Xcode at /Applications/Xcode-15.3.0.app/Contents/Developer
    • Build 15E204a
    • CocoaPods version 1.15.2

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2024.1)
    • Android Studio at /Users/nexus/Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 17.0.10+0-17.0.10b1087.21-11609105)

[✓] IntelliJ IDEA Ultimate Edition (version 2023.2.5)
    • IntelliJ at /Users/nexus/Applications/IntelliJ IDEA Ultimate.app
    • Flutter plugin version 77.2.2
    • Dart plugin version 232.10286

[✓] VS Code (version 1.91.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.92.0

[✓] Connected device (5 available)
    • Nexus (mobile)                  • 00008020-001875E83A38002E • ios            • iOS 17.5.1 21F90
    • Dean’s iPad (mobile)            • 00008103-000825C811E3401E • ios            • iOS 17.5.1 21F90
    • macOS (desktop)                 • macos                     • darwin-arm64   • macOS 14.4.1 23E224 darwin-arm64
    • Mac Designed for iPad (desktop) • mac-designed-for-ipad     • darwin         • macOS 14.4.1 23E224 darwin-arm64
    • Chrome (web)                    • chrome                    • web-javascript • Google Chrome 126.0.6478.127

[✓] Network resources
    • All expected network resources are available.

• No issues found!
[!] Flutter (Channel master, 3.24.0-1.0.pre.114, on macOS 14.4.1 23E224 darwin-arm64, locale en-GB)
    • Flutter version 3.24.0-1.0.pre.114 on channel master at /Users/nexus/dev/sdks/flutters
    ! Warning: `flutter` on your path resolves to /Users/nexus/dev/sdks/flutter/bin/flutter, which is not inside your current Flutter SDK checkout at /Users/nexus/dev/sdks/flutters. Consider adding /Users/nexus/dev/sdks/flutters/bin to the front of your path.
    ! Warning: `dart` on your path resolves to /Users/nexus/dev/sdks/flutter/bin/dart, which is not inside your current Flutter SDK checkout at /Users/nexus/dev/sdks/flutters. Consider adding /Users/nexus/dev/sdks/flutters/bin to the front of your path.
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 82b63ff27d (26 hours ago), 2024-07-14 05:07:36 -0400
    • Engine revision a921637f16
    • Dart version 3.6.0 (build 3.6.0-36.0.dev)
    • DevTools version 2.37.1
    • If those were intentional, you can disregard the above warnings; however it is recommended to use "git" directly to perform update checks and upgrades.

[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
    • Android SDK at /Users/nexus/Library/Android/sdk
    • Platform android-34, build-tools 34.0.0
    • Java binary at: /Users/nexus/Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 17.0.10+0-17.0.10b1087.21-11609105)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 15.3)
    • Xcode at /Applications/Xcode-15.3.0.app/Contents/Developer
    • Build 15E204a
    • CocoaPods version 1.15.2

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2024.1)
    • Android Studio at /Users/nexus/Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 17.0.10+0-17.0.10b1087.21-11609105)

[✓] IntelliJ IDEA Ultimate Edition (version 2023.2.5)
    • IntelliJ at /Users/nexus/Applications/IntelliJ IDEA Ultimate.app
    • Flutter plugin version 77.2.2
    • Dart plugin version 232.10286

[✓] VS Code (version 1.91.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.92.0

[✓] Connected device (5 available)
    • Nexus (mobile)                  • 00008020-001875E83A38002E • ios            • iOS 17.5.1 21F90
    • Dean’s iPad (mobile)            • 00008103-000825C811E3401E • ios            • iOS 17.5.1 21F90
    • macOS (desktop)                 • macos                     • darwin-arm64   • macOS 14.4.1 23E224 darwin-arm64
    • Mac Designed for iPad (desktop) • mac-designed-for-ipad     • darwin         • macOS 14.4.1 23E224 darwin-arm64
    • Chrome (web)                    • chrome                    • web-javascript • Google Chrome 126.0.6478.127

[✓] Network resources
    • All expected network resources are available.

! Doctor found issues in 1 category.
hmtdttj4

hmtdttj42#

似乎在RenderOpacity中存在一个涉及重绘边界逻辑的问题。
当alpha值在零和非零之间转换时,RenderOpacity.isRepaintBoundary会发生变化。当这种情况发生时,会调用markNeedsCompositingBitsUpdate,但出于某种原因,小部件仍然渲染为被裁剪到原始大小的样子。
如果我将_opacity动画更改为从0.01开始,这样alpha值永远不会为零,那么这个渲染就会正确。
@jonahwilliams

相关问题