【问题标题】:Flutter How to build a CustomScrollView with a non scrollable partFlutter 如何构建具有不可滚动部分的 CustomScrollView
【发布时间】:2018-06-30 07:41:27
【问题描述】:

我希望在顶部有一个不可滚动部分的视图,例如在底部有一个标签栏,我可以滚动到顶部以显示项目列表并能够在列表内滚动项目。

为此,我使用了一个 CustomScrollView,暂时用一个 sliver 网格代替图像,一个 sliver 应用程序栏用于标签栏,一个 sliverFixedExtentList 用于列表。

  Widget build(BuildContext context) {
return new Scaffold(
    body: new CustomScrollView(
      slivers: <Widget>[
        new SliverGrid(
          gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
            childAspectRatio: 0.58,
            crossAxisCount: 1,

          ),
          delegate: new SliverChildBuilderDelegate(
                (BuildContext context, int index) {
              return new Container(

                  color: Colors.red,
                  child: new Container(
                    color: Colors.green,
                    child: new Text('IMG HERE'),
                  )
              );
            },
            childCount: 1,

          ),
        ),

        new SliverAppBar(
          title: new Text("title"),
          floating: false,
          pinned: true,
          primary: true,
          actions: <Widget>[
            new IconButton(
              icon: const Icon(Icons.arrow_upward),
              onPressed: () {
              },
            ),

          ],
          bottom: new TabBar(
            controller: _tabController,
            isScrollable: true,
            tabs: _bars,
          ),
        ),

        new SliverFixedExtentList(
          itemExtent: 100.0,
          delegate: new SliverChildBuilderDelegate(
                (BuildContext context, int index) {
              return new Container(
                alignment: Alignment.center,
                color: Colors.lightGreen[100 * (index % 9)],
                child: new Text('list item $index'),
              );
            },
          ),
        ),
      ],
    )
);

}

但我有 3 个问题:

  1. 我不知道如何在此处为 slivergrid 设置不可滚动的 sliver。
  2. 我不知道如何让 appBar 在启动时准确地放置在屏幕底部。
  3. 我的列表有问题,当appbar到达顶部时,列表跳转了一些项目,它似乎代表了sliverGrid元素的大小。

谢谢

【问题讨论】:

    标签: flutter


    【解决方案1】:

    我已经尝试过您的代码,但那里似乎缺少一些重要的部分。我看不到_tabController_bars 背后的代码是什么,所以我只制作了自己的_tabController_bars。我已经运行了它,这就是我到目前为止所得到的:

    启动时:

    浏览直到AppBar 到达顶部。

    因此,出于演示目的,我对您的代码进行了一些更改:

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
            visualDensity: VisualDensity.adaptivePlatformDensity,
          ),
          home: MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage>
        with SingleTickerProviderStateMixin {
      TabController _tabController;
      List<Widget> _bars = [
        Tab(icon: Icon(Icons.image)),
        Tab(icon: Icon(Icons.image)),
      ];
      int _selectedIndex = 0;
    
      @override
      void initState() {
        super.initState();
        _tabController = TabController(length: _bars.length, vsync: this);
        _tabController.addListener(() {
          setState(() {
            _selectedIndex = _tabController.index;
          });
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
            body: new CustomScrollView(
          slivers: <Widget>[
            new SliverGrid(
              gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
                childAspectRatio: .69,
                crossAxisCount: 1,
              ),
              delegate: new SliverChildBuilderDelegate(
                (BuildContext context, int index) {
                  return SafeArea(
                    child: new Container(
                      color: Colors.green,
                      child: new Text('IMG HERE'),
                    ),
                  );
                },
                childCount: 1,
              ),
            ),
            new SliverAppBar(
              title: new Text("title"),
              floating: false,
              pinned: true,
              primary: true,
              actions: <Widget>[
                new IconButton(
                  icon: const Icon(Icons.arrow_upward),
                  onPressed: () {},
                ),
              ],
              bottom: new TabBar(
                controller: _tabController,
                isScrollable: true,
                tabs: _bars,
              ),
            ),
            new SliverFixedExtentList(
              itemExtent: 100.0,
              delegate: new SliverChildBuilderDelegate(
                (BuildContext context, int index) {
                  return new Container(
                    alignment: Alignment.center,
                    color: Colors.lightGreen[100 * (index % 9)],
                    child: new Text('list item $index'),
                  );
                },
              ),
            ),
          ],
        ));
      }
    }
    

    这是输出:

    如您所见,我已经使用了childAspectRatio 的值,以便您可以将 AppBar` 默认设置在屏幕底部,这就是我对您的问题 2 的理解。

    对于第 3 个问题,您的代码似乎运行良好。我能够正确地看到从 0 开始正确排序的升序列表项。

    对于第 1 个问题,我很困惑您希望它如何发生。您不希望 SliverGrid 可滚动,但您希望 AppBar 在滚动后位于屏幕顶部。我想在这部分提供更多背景信息可以让每个人都清楚。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-12-28
      • 2019-11-20
      • 2021-08-24
      • 2019-11-20
      • 2021-11-15
      • 2023-04-05
      • 1970-01-01
      • 2021-11-07
      相关资源
      最近更新 更多