简体   繁体   中英

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

I have created the Search bar, I need to add a functionality to it so that whenever the user scrolls down, the search bar turns into an icon in the appbar which can be clicked again to expand.

This is the appbar container

 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) {}), ], ), ), ),

This is the code for the search bar that would be present in the appbar

 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), ), ), ), ); } }

You can use LayoutBuilder to get sliver AppBar biggest height. When biggest.height = 80.0, it actually means sliver appbar is collapsed.

Here is a some example:

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());
        },
      ),
    ));
  }
}

I'm sorry for messy code but, I hope you get the idea

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM