颤抖-如何在灵活使用应用栏的同时使我的应用栏充当材料搜索小部件

时间:2018-09-29 00:10:34

标签: flutter flutter-layout

我希望我的应用程序栏在向下滚动或用户搜索某些内容时充当固定的应用程序栏。

SliverAppBar(
  title: new TextField(
    style: Theme.of(context).primaryTextTheme.title,
    decoration: InputDecoration(
      hintText: '검색',
    ),
  ),
),

searching


但是我想将其向上滚动且用户未在搜索时将其绘制为灵活的应用栏。

flexibleSpace: new FlexibleSpaceBar(
  centerTitle: false,
  title: new TextField(
    style: Theme.of(context).primaryTextTheme.title,
    decoration: InputDecoration(
      hintText: '검색',
    ),
  ),
  background: Stack(
    fit: StackFit.expand,
    children: <Widget>[
      SizedBox(
        height: 256.0,
        child: Container(
          child: Padding(
            padding: const EdgeInsets.only(top: 24.0),
            child: Column(
              children: <Widget>[
                Align(
                  alignment: Alignment.topLeft,
                  child: FlutterLogo(
                    size: 64.0,
                  ),
                ),
                Padding(padding: const EdgeInsets.only(bottom: 24.0)),
                ListTile(
                  title: Text('Some Text'),
                ),
              ],
            ),
          ),
        ),
      ),
      // This gradient ensures that the toolbar icons are distinct
      // against the background image.
    ],
  ),
),

scrolled-up

使用第二种方法向上滚动时,搜索字段会转换为右上角的一点。

3 个答案:

答案 0 :(得分:0)

可以通过将标题内容移动到另一个SliverList来实现效果。

从SliverAppBar中删除flexibleSpace,并将flexibleSpace.background的内容移到SliverAppBar之前的

示例:

@override
Widget build(BuildContext context) {
  return new CustomScrollView(
    slivers: <Widget>[
      new SliverList(
          delegate: new SliverChildListDelegate(<Widget>[
        Align(
          alignment: Alignment.topLeft,
          child: FlutterLogo(size: 64.0),
        ),
        ListTile(
          title: Text('Some Text'),
        ),
        ListTile(),
      ])),
      new SliverAppBar(
        backgroundColor: Theme.of(context).scaffoldBackgroundColor,
        elevation: 0.0,
        automaticallyImplyLeading: false,
        pinned: true,
        floating: false,
        title: new TextField(
          focusNode: _searchFocusNode,
          style: Theme.of(context).primaryTextTheme.title,
          decoration: InputDecoration(
            border: OutlineInputBorder(borderRadius: BorderRadius.all(Radius.circular(8.0))),
            suffixIcon: Icon(Icons.search),
            hintText: '검색',
          ),
        ),
      ),
      new SliverList(
        delegate: new SliverChildListDelegate(List.generate(
            100,
            (i) => ListTile(
                  title: Text('Scroll'),
                )).toList()),
      ),
    ],
  );
}

答案 1 :(得分:0)

我已在此要点中编写了一个getMaterialSerach();方法,该方法具有所需的确切材料搜索视图。只需像下面这样在appBar:小部件中添加getMaterialSearch()即可。 here is the gist for getMaterialSearch();

@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: getMaterialSearchBar(),
      body: Center(
        child: Container(),
      ),
    );
  }

答案 2 :(得分:0)

这是我在 SliverAppBar 中带有 TextField 和 Tabs 的代码:

enter image description here

NestedScrollView(
                    controller: model.mainScrollController,
                    headerSliverBuilder: (context, innerBoxIsScrolled) {
                      return [
                        /// https://github.com/flutter/flutter/issues/54059
                        SliverOverlapAbsorber(
                          handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
                          sliver: SliverAppBar(
                            automaticallyImplyLeading: false,
                            pinned: true,
                            floating: true,
                            snap: true,
                            expandedHeight: 100,
                            flexibleSpace: FlexibleSpaceBar(
                              collapseMode: CollapseMode.pin,
                              background: Padding(
                                padding: const EdgeInsets.symmetric(vertical: 16.0),
                                child: Row(
                                  children: [
                                    BackButton(
                                      color: Colors.white,
                                    ),
                                    Flexible(
                                      child: TextField(
                                        controller: model.searchController,
                                        decoration: InputDecoration(
                                            focusColor: Colors.blueAccent,
                                            hoverColor: Colors.blueAccent,
                                            fillColor: Colors.white,
                                            filled: true,
                                            isDense: true,
                                            prefixIconConstraints: BoxConstraints(maxHeight: 24, maxWidth: 48),
                                            prefixIcon: Padding(
                                              padding: const EdgeInsets.symmetric(horizontal: 8.0),
                                              child: Icon(Icons.search_outlined),
                                            ),
                                            hintText: 'Search...'),
                                      ),
                                    ),
                                    IconButton(
                                      icon: Icon(
                                        Icons.add,
                                        color: Colors.white,
                                      ),
                                      onPressed: () {
                                        ExtendedNavigator.named('topNav').push(Routes.newExerciseView);
                                      },
                                      tooltip: 'Create Exercise',
                                    ),
                                  ],
                                ),
                              ),
                            ),
                            bottom: TabBar(
                              labelPadding: EdgeInsets.only(bottom: 8),
                              indicatorWeight: 3,
                              indicatorSize: TabBarIndicatorSize.label,
                              tabs: [
                                Text('All'),
                                Text('Custom'),
                                Text('Favorites'),
                              ],
                            ),
                          ),
                        ),
                      ];
                    },
                    body: TabBarView(
                        children: [
                      AllExercises(),
                      CustomExercises(),
                      FavoriteExercises(),
                    ]),
                  ),

有几个关键部分可以使这项工作正常进行,首先是您需要使用 SliverAppBar 的 flexibleSpace 属性来添加您的搜索小部件。如果您尝试将其添加到 title 属性中,则 TextField 只会被压扁但永远不会离开屏幕。

其次,确保FlexibleSpaceBar 的collapseMode 设置为CollapseMode.pin。这使得flexibleSpace的内容滚动到屏幕外并且不会改变大小。

最后,将固定在 sliverAppBar 上设置为 true,以便 TabBar 保持不变。