在应用栏中创建一个在 Flutter 中向下滚动时变成图标的搜索?

Creating a Search in appbar that turns into an icon when scrolling down in Flutter?

我已经创建了搜索栏,我需要给它添加一个功能,这样每当用户向下滚动时,搜索栏就会变成应用栏中的一个图标,可以再次点击它展开。

这是应用栏容器

Container(
              height: 122,
              color: AppColors.kDefaultPink,
              child: Padding(
                padding: const EdgeInsets.all(10.0),
                child: Column(
                  children: <Widget>[
                    //Location text
                    SizedBox(height: 10.0,),
                    Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        Icon(
                          Icons.location_on,
                          color: Colors.white,
                        ),
                        SizedBox(width: 12.0),
                        Text("Delhi NCR",style: TextStyle(color: Colors.white, fontSize: 18.0),),
                      ],
                    ),
                    SizedBox(height: 20.0,),
                    //SearchBOX
                    SearchBox(onChanged: (value) {}),
                  ],
                ),
              ),
            ),

这是将出现在应用栏中的搜索栏代码

import 'package:flutter/material.dart';
import 'package:zattireuserapp/views/AppColors.dart';

class SearchBox extends StatelessWidget {

  final ValueChanged onChanged;

  const SearchBox({Key key, this.onChanged}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 5),
      child: Container(
        width: 390,
        height: 45,
        margin: EdgeInsets.symmetric(horizontal: 22.0),
        decoration: BoxDecoration(
          color: Colors.white.withOpacity(1),
          borderRadius: BorderRadius.circular(12),
        ),
        child: TextField(
          onChanged: onChanged,
          style: TextStyle(color: AppColors.blackColor),
          decoration: InputDecoration(
            enabledBorder: InputBorder.none,
            focusedBorder: InputBorder.none,
            prefixIcon: Icon(Icons.search),
            hintText: 'Search for anything',
            hintStyle: TextStyle(fontSize: 15),
          ),
        ),
      ),
    );
  }
}

您可以使用 LayoutBuilder 获得 sliver AppBar 的最大高度。当biggest.height = 80.0时,实际上意味着sliver appbar被折叠了。

这是一个例子:

import 'package:flutter/material.dart';

void main() => runApp(MaterialApp(
      home: MyApp(),
    ));

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  var top = 0.0;
  ScrollController _scrollController;
  
    @override
  void initState() {
    _scrollController = ScrollController(keepScrollOffset: true);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: NestedScrollView(
          controller: _scrollController,
      headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
        return <Widget>[
          SliverAppBar(
              expandedHeight: 200.0,
              floating: false,
              pinned: true,
              flexibleSpace: LayoutBuilder(
                  builder: (BuildContext context, BoxConstraints constraints) {
                top = constraints.biggest.height;
                return FlexibleSpaceBar(
                    centerTitle: true,
                    title: top >= 80 ? TextField() : IconButton(icon: Icon(Icons.search), onPressed: () => _scrollController.jumpTo(0)) // condition
                );
              })),
        ];
      },body: ListView.builder(
        itemCount: 100,
        itemBuilder: (context,index){
          return Text("List Item: " + index.toString());
        },
      ),
    ));
  }
}

对于混乱的代码,我深表歉意,但我希望你能理解