将 Scaffold 放入 NestedScrollview 时的奇怪行为?在 SliverAppbar 下剪辑时自动滚动到顶部

Posted

技术标签:

【中文标题】将 Scaffold 放入 NestedScrollview 时的奇怪行为?在 SliverAppbar 下剪辑时自动滚动到顶部【英文标题】:Weird behaviour when put Scaffold inside NestedScrollview? Auto scroll to top when clip under SliverAppbar 【发布时间】:2021-11-19 13:17:35 【问题描述】:

我有一个奇怪的行为,单击 listview.builder 的第一个索引时会自动滚动到顶部。我想实现一个底部的 SliverAppbar 是一个 TabBar 和一个带有 TabView 的主体。每个 TabView 都有一个带有 FloatingButton 的 Scaffold。

这是我重现该问题的代码。 只需点击接近应用栏的索引 0,滚动视图就会自动滚动到顶部。

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget 
  static const String _title = 'Flutter Code Sample';

  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      title: _title,
      home: MyStatelessWidget(),
    );
  


/// This is the stateless widget that the main application instantiates.
class MyStatelessWidget extends StatelessWidget 
  MyStatelessWidget(Key? key) : super(key: key);

  @override
  Widget build(BuildContext context) 
    return DefaultTabController(
      length: 3,
      child: NestedScrollView(
        headerSliverBuilder: (context, innerBoxIsScrolled) 
          return [
            SliverAppBar(
              floating: true,
              pinned: true,
              title: Text(
                'Appbar',
                style: TextStyle(color: Colors.black),
              ),
              expandedHeight: 100,
            ),
          ];
        ,
        body: Builder(builder: (context) 
          final ScrollController scrollController =
              PrimaryScrollController.of(context)!;
          return Scaffold(
            body: ListView.separated(
              controller: scrollController,
              padding: EdgeInsets.zero,
              itemBuilder: (context, index) 
                return Container(
                  height: 100,
                  width: double.infinity,
                  child: Text('Index: $index'),
                );
              ,
              itemCount: 1000,
              separatorBuilder: (BuildContext context, int index) 
                return Divider();
              ,
            ),
          );
        ),
      ),
    );
  

颤振医生-v

[✓] Flutter (Channel stable, 2.5.1, on macOS 11.4 20F71 darwin-arm, locale en)
    • Flutter version 2.5.1 at /Users/Dakrain/Tools/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision ffb2ecea52 (10 days ago), 2021-09-17 15:26:33 -0400
    • Engine revision b3af521a05
    • Dart version 2.14.2

[✓] android toolchain - develop for Android devices (Android SDK version 31.0.0)
    • Android SDK at /Users/Dakrain/Library/Android/sdk
    • Platform android-31, build-tools 31.0.0
    • Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7249189)
    • All Android licenses accepted.

[✓] Xcode - develop for ios and macOS
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 12.5.1, Build version 12E507
    • CocoaPods version 1.10.1

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

[✓] Android Studio (version 2020.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 11.0.10+0-b96-7249189)

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

[✓] Connected device (3 available)
    • iPhone của Khoa (mobile) • cd7cb393a5d14f4110ff72e4e2744e367ce7aeae • ios            • iOS 12.5.4 16H50
    • iPhone 12 Pro (mobile)   • 34C110D0-44D4-444A-902F-64911EE420E1     • ios            •
      com.apple.CoreSimulator.SimRuntime.iOS-14-5 (simulator)
    • Chrome (web)             • chrome                                   • web-javascript • Google Chrome
      92.0.4515.107

• No issues found!

问题的 GIF 图片 https://drive.google.com/file/d/1P7XyFMwpkOfdgW2UFXHmPNrDT4_rYufH/view?usp=sharing

【问题讨论】:

【参考方案1】:

啊,反正有点乱。 Scaffold 是您的“物质主义”页面的骨架,它具有解剖结构。比如appBarbodybottomNavigationBar等。问题是NestedScrollView是一个小部件,你不要用Widget包裹脚手架,因为Scaffold是小部件的骨架,试着把而是在body 内。

/// This is the stateless widget that the main application instantiates.
class MyStatelessWidget extends StatelessWidget 
  MyStatelessWidget(Key? key) : super(key: key);

  @override
  Widget build(BuildContext context) 
    return Scaffold(
       body:DefaultTabController(
      length: 3,
      child: NestedScrollView(
        headerSliverBuilder: (context, innerBoxIsScrolled) 
          return [
            SliverAppBar(
              floating: true,
              pinned: true,
              title: Text(
                'Appbar',
                style: TextStyle(color: Colors.black),
              ),
              expandedHeight: 100,
            ),
          ];
        ,
        body: Builder(builder: (context) 
          final ScrollController scrollController =
              PrimaryScrollController.of(context)!;
          return ListView.separated(
              controller: scrollController,
              padding: EdgeInsets.zero,
              itemBuilder: (context, index) 
                return Container(
                  height: 100,
                  width: double.infinity,
                  child: Text('Index: $index'),
                );
              ,
              itemCount: 1000,
              separatorBuilder: (BuildContext context, int index) 
                return Divider();
              ,
          );
        ),
      ),
    );
  

【讨论】:

我正在尝试将 TabView 放在带有 3 个脚手架的 NestedScrollView 的主体中,并且每个都有自己的浮动按钮。还有其他解决方法吗? 天哪,1页内有3个脚手架?伙计,这是错误的。通常一页只需要 1 个脚手架,否则 TabView 可以使用常规容器/单个子滚动视图和列 是的,我有一个页面使用 3 种不同的动作作为浮动动作,所以我试图将它们分开。

以上是关于将 Scaffold 放入 NestedScrollview 时的奇怪行为?在 SliverAppbar 下剪辑时自动滚动到顶部的主要内容,如果未能解决你的问题,请参考以下文章

如何将符合 Material Design 标准的填充应用到我的 Flutter Scaffold?

Flutter SnackBar 在 Scaffold 中留下不可见的填充

如何防止scaffold.css 覆盖我的自定义css?

搭建第一个Dapp应用——基于SmartDev-Scaffold生成SpringBoot项目——2021.5.3

Rails Scaffold 方法的最佳实践

在 Scaffold Jetpack Compose 内的特定屏幕上隐藏顶部和底部导航器