flutter / flutter

Flutter makes it easy and fast to build beautiful apps for mobile and beyond
https://flutter.dev
BSD 3-Clause "New" or "Revised" License
166.19k stars 27.49k forks source link

Setting state while DraggableScrollableSheet is over-scrolled with BouncingScrollPhysics collapses the sheet #154814

Open rasitayaz opened 2 months ago

rasitayaz commented 2 months ago

Steps to reproduce

  1. Copy code sample below into main.dart of a new Flutter project.
  2. Run it on an Android emulator or iOS simulator.
  3. Like in the video below, over-scroll the bottom sheet at the top, and then trigger setState for the child content of the sheet by swiping the PageView.
  4. To reproduce the issue more easily, replace PageViewSheet with TimerSheet at line 40, and just over-scroll the sheet.

Expected results

Bottom sheet and scrollable positions to be preserved.

Actual results

Bottom sheet collapses to its minimum size (minChildSize attribute).

Code sample

Code sample ```dart import 'package:flutter/material.dart'; void main() => runApp(const App()); class App extends StatelessWidget { const App({super.key}); @override Widget build(BuildContext context) { return const MaterialApp( home: TestPage(), ); } } class TestPage extends StatelessWidget { const TestPage({super.key}); @override Widget build(BuildContext context) { return Material( child: Stack( children: [ DraggableScrollableSheet( initialChildSize: 0.5, minChildSize: 0.25, maxChildSize: 1, snap: true, snapSizes: const [0.25, 0.5, 1], snapAnimationDuration: const Duration(milliseconds: 200), builder: (context, scrollController) { return SafeArea( bottom: false, child: ColoredBox( color: Colors.green, child: SingleChildScrollView( controller: scrollController, padding: const EdgeInsets.symmetric(vertical: 64), physics: const BouncingScrollPhysics(), child: const PageViewSheet(), // TimerSheet(), ), ), ); }, ), ], ), ); } } class PageViewSheet extends StatefulWidget { const PageViewSheet({super.key}); @override State createState() => _PageViewSheetState(); } class _PageViewSheetState extends State { final _pageController = PageController(viewportFraction: 0.2); var _pageIndex = 0; @override void dispose() { _pageController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Column( children: [ Text('Current Page: $_pageIndex'), const SizedBox(height: 32), SizedBox( height: 100, child: PageView( controller: _pageController, onPageChanged: (value) { setState(() => _pageIndex = value); }, children: [ for (var i = 0; i < 10; i++) Container( color: i.isEven ? Colors.red : Colors.blue, child: Center( child: Text('Page $i'), ), ), ], ), ), ], ); } } class TimerSheet extends StatefulWidget { const TimerSheet({super.key}); @override State createState() => _TimerSheetState(); } class _TimerSheetState extends State { var _seconds = 0; @override void initState() { super.initState(); Future.doWhile(() async { await Future.delayed(const Duration(seconds: 1)); if (!mounted) return false; setState(() => _seconds++); return true; }); } @override Widget build(BuildContext context) { return Column( children: [ Text('Seconds: $_seconds'), ], ); } } ```

Screenshots or Video

Screenshots / Video demonstration [example 1.webm](https://github.com/user-attachments/assets/90d49eb3-9258-405b-bcb5-ef81cb7d2a1b) [example 2.webm](https://github.com/user-attachments/assets/11be11ee-1c0d-4183-a837-eb46fc021094)

Logs

Logs ```console [Paste your logs here] ```

Flutter Doctor output

Doctor output ```console [✓] Flutter (Channel stable, 3.24.2, on macOS 14.6.1 23G93 darwin-arm64, locale en-TR) • Flutter version 3.24.2 on channel stable at /Users/rasitayaz/Library/flutter • Upstream repository https://github.com/flutter/flutter.git • Framework revision 4cf269e36d (6 days ago), 2024-09-03 14:30:00 -0700 • Engine revision a6bd3f1de1 • Dart version 3.5.2 • DevTools version 2.37.2 [✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0) • Android SDK at /Users/rasitayaz/Library/Android/sdk • Platform android-34, build-tools 34.0.0 • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b829.9-10027231) • All Android licenses accepted. [✓] Xcode - develop for iOS and macOS (Xcode 15.4) • Xcode at /Applications/Xcode.app/Contents/Developer • Build 15F31d • CocoaPods version 1.15.2 [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [✓] Android Studio (version 2022.3) • Android Studio at /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.6+0-17.0.6b829.9-10027231) [✓] VS Code (version 1.92.2) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.96.0 [✓] Connected device (6 available) • sdk gphone64 arm64 (mobile) • emulator-5554 • android-arm64 • Android 14 (API 34) (emulator) • Raşit’s iPhone (mobile) • 00008120-001A35E63E83C01E • ios • iOS 17.6.1 21G93 • iPhone 15 Pro (mobile) • 1EB73D3B-9A8A-413E-9A46-AF09906D2A28 • ios • com.apple.CoreSimulator.SimRuntime.iOS-17-5 (simulator) • macOS (desktop) • macos • darwin-arm64 • macOS 14.6.1 23G93 darwin-arm64 • Mac Designed for iPad (desktop) • mac-designed-for-ipad • darwin • macOS 14.6.1 23G93 darwin-arm64 • Chrome (web) • chrome • web-javascript • Google Chrome 118.0.5993.96 [✓] Network resources • All expected network resources are available. • No issues found! ```
darshankawar commented 2 months ago

Thanks for the detailed report @rasitayaz I was able to replicate the reported behavior upon running in Android emulator. When we try to scroll down the pageView, it shrinks to minimum size, wherein the pageViews are also cut-off.

Stable : 3.24.2
Master: 3.25.0-1.0.pre.269