【问题标题】:Pin item when scrolling up向上滚动时固定项目
【发布时间】:2019-09-25 10:06:59
【问题描述】:

所以我有以下屏幕:

我正在寻找一种方法,使当用户向上滚动时,包含进度条和这 4 个数据字段 (ItemHeader) 的小部件将向上滚动,但搜索容器 (SearchTextField) 将被固定 (到顶部)。当然,当用户向下滚动时,它应该会重新出现。

我找到的所有解决方案都解决了使用标签的情况。代码添加在下面,谢谢!

Scaffold(
      backgroundColor: Theme.of(context).backgroundColor,
      appBar: MyAppBar(
        true,
        title: constructParentName,
        parentTitle: siteParentName,
      ),
      endDrawer: MyDrawer(),
      body: _isLoading
          ? Center(
              child: CircularProgressIndicator(),
            )
          : Column(
              children: <Widget>[
                ItemHeader("24", "23", "33"), //This is the widget I would like to hide while scrolling up
                SearchTextField(controller),
                Expanded(
                  child: ListView.builder(
                    itemBuilder: (BuildContext context, int i) {
                      return filter == null || filter == ""
                          ? ItemDetail(
                              itemId: subconstructs[i].subconstructId,
                              itemName: subconstructs[i].subconstructName,
                              tasksDone: subconstructs[i].tasksDone,
                              tasksRejected: subconstructs[i].tasksRejected,
                              tasksPending: subconstructs[i].tasksPending,
                              authToken: authToken,
                              constructParentId: constructParentId,
                              siteParentId: siteAncestorId,
                              callBack: () {
                                return PageEnum.Subconstructs;
                              },
                            )
                          : subconstructs[i]
                                  .subconstructName
                                  .toString()
                                  .toLowerCase()
                                  .contains(filter.toLowerCase())
                              ? ItemDetail(
                                  itemId: subconstructs[i].subconstructId,
                                  itemName: subconstructs[i].subconstructName,
                                  tasksDone: subconstructs[i].tasksDone,
                                  tasksRejected: subconstructs[i].tasksRejected,
                                  tasksPending: subconstructs[i].tasksPending,
                                  authToken: authToken,
                                  constructParentId: constructParentId,
                                  siteParentId: siteAncestorId,
                                  callBack: () {
                                    return PageEnum.Subconstructs;
                                  },
                                )
                              : new Container();
                    },
                    itemCount: subconstructs.length,
                  ),
                ),
              ],
            ),
      bottomNavigationBar: buildBottomNavBar(),
    );

【问题讨论】:

  • @AmitPrajapati 抱歉,我无法理解这应该如何解决我的问题
  • 你的代码看起来很完美,试试 resizeToAvoidBottomInset: true in scaffold
  • @AmitPrajapati 目前 ItemHeader 和 SearchTextField 小部件不在任何滚动类型的列表中,因此它们不可滚动。该标志并没有真正改变任何行为

标签: flutter dart


【解决方案1】:

我只是将您的标题容器包装在一个 Column 小部件中。

    class ListViewDemo extends StatefulWidget {
    @override
    State<StatefulWidget> createState() {
        return ListViewDemoState();
    }
    }

    class ListViewDemoState extends State<ListViewDemo> {
    @override
    Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
            title: Text("ListView"),
            ),
            body: Column(
            children: <Widget>[
                Column(
                children: <Widget>[
                    Container(
                    color: Colors.red,
                    child: Text(
                        "  Header1",
                        style: new TextStyle(fontSize: 16.0, color: Colors.black),
                    ),
                    ),
                    Container(
                    color: Colors.blue,
                    child: Text(
                        "  Header2",
                        style: new TextStyle(fontSize: 16.0, color: Colors.black),
                    ),
                    ),
                ],
                ),
                Expanded(
                child: ListView.builder(
                    itemCount: 100,
                    itemExtent: 50.0,
                    itemBuilder: (BuildContext context, int index) {
                        return ListTile(title: Text("$index"));
                    }),
                )
            ],
            ));
    }
    }

方法 2

    import 'package:flutter/material.dart';
    import 'dart:math' as math;

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

    class MyApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
        return MaterialApp(
        home: Scaffold(
            appBar: AppBar(title: Text('List Demo')),
            body: CollapsingList(),
        ),
        );
    }
    }

    class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
    _SliverAppBarDelegate({
        @required this.minHeight,
        @required this.maxHeight,
        @required this.child,
    });

    final double minHeight;
    final double maxHeight;
    final Widget child;

    @override
    double get minExtent => minHeight;

    @override
    double get maxExtent => math.max(maxHeight, minHeight);

    @override
    Widget build(
        BuildContext context, double shrinkOffset, bool overlapsContent) {
        return new SizedBox.expand(child: child);
    }

    @override
    bool shouldRebuild(_SliverAppBarDelegate oldDelegate) {
        return maxHeight != oldDelegate.maxHeight ||
            minHeight != oldDelegate.minHeight ||
            child != oldDelegate.child;
    }
    }

    class CollapsingList extends StatelessWidget {


    SliverPersistentHeader makeHeader(String headerText) {
        return SliverPersistentHeader(
        pinned: true,
        delegate: _SliverAppBarDelegate(
            minHeight: 150.0,
            maxHeight: 150.0,
            child: Container(
                color: Colors.lightBlue, child: Center(child: Text(headerText))),
        ),
        );
    }


    @override
    Widget build(BuildContext context) {
        return CustomScrollView(
        slivers: <Widget>[
            SliverFixedExtentList(
            itemExtent: 150.0,
            delegate: SliverChildListDelegate(
                [
                Container(
                    color: Colors.red,
                    child: Center(
                    child: Text(
                        "Header Section 1",
                        style: new TextStyle(fontSize: 16.0, color: Colors.black),
                    ),
                    ),
                )
                ],
            ),
            ),
            makeHeader('Header Section 2'),
            SliverFixedExtentList(
                itemExtent: 50.0,
                delegate:
                    SliverChildBuilderDelegate((BuildContext context, int index) {
                return new Container(
                    alignment: Alignment.center,
                    child: new Text('List item $index'),
                );
                }, childCount: 100)),
        ],
        );
    }
    }

【讨论】:

  • 那么在这个例子中,如何让 Header1 向上滚动而 Header2 保持固定?
  • 你的意思是你想要滚动 header1,是否需要 Listview appbar 滚动或 appbar 会留在那里,只滚动 header1 和你的 ListView,你的搜索固定在那里吗?
  • 是的,这正是我所说的,appbar-stays,header1- 与 listview 一起向上滚动,search bar-stays
  • 现在这就是我想要的。非常感谢!
猜你喜欢
  • 2018-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-01
  • 1970-01-01
  • 2018-06-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多