Arnav
Arnav

Reputation: 1454

How to make a floating AppBar in Flutter?

enter image description here

I want to make a floating AppBar in Flutter that overlays on my UI and dismisses when the user scrolls up. I have tried using this dependency - https://pub.dev/packages/material_floating_search_bar but this is only for searching through something.

Update: This is my code -

DefaultTabController(
      length: 2,
      child: Scaffold(
          body: Stack(
        children: [
          Positioned(
            top: 15,
            left: 15,
            right: 15,
            child: SafeArea(
              child: ClipRRect(
                borderRadius: BorderRadius.circular(12),
                child: AppBar(
                  title: Text('Hello', style: kTasksStyle),
                  centerTitle: true,
                  backgroundColor: kGreen,
                ),
              ),
            ),
          ),
        ],
      )),
    );

How do I add a TabBar in the bottom parameter of AppBar?

Upvotes: 1

Views: 4638

Answers (2)

CopsOnRoad
CopsOnRoad

Reputation: 267554

Screenshot:

enter image description here


For simplicity, I used a ListView.

Code:

class _MainPageState extends State<HomePage> {
  final double _appBarHeight = 56;
  final double _topPadding = 20;
  ScrollController _controller;
  double _opacity = 1;

  @override
  void initState() {
    super.initState();
    _controller = ScrollController();
    _controller.addListener(_listener);
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  void _listener() {
    final offset = _controller.offset;
    if (offset > _appBarHeight) {
      if (_opacity != 0) {
        setState(() {
          _opacity = 0;
          if (_opacity < 0) _opacity = 0;
        });
      }
    } else {
      setState(() {
        _opacity = 1 - (offset / _appBarHeight);
        if (_opacity > 1) _opacity = 1;
      });
    }
  }

  Widget get _mainContent {
    return ListView.builder(
      controller: _controller,
      padding: EdgeInsets.only(top: _topPadding + _appBarHeight),
      itemCount: 20,
      itemBuilder: (_, i) => ListTile(title: Text('Item $i')),
    );
  }

  Widget get _appBar {
    return Opacity(
      opacity: _opacity,
      child: SizedBox.fromSize(
        size: Size.fromHeight(_appBarHeight),
        child: AppBar(
          title: Text('AppBar'),
          centerTitle: false,
          backgroundColor: Colors.grey,
          leading: Icon(Icons.menu),
          actions: [
            IconButton(
              icon: Icon(Icons.place),
              onPressed: () {},
            )
          ],
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
          _mainContent,
          Positioned(
            top: _topPadding,
            left: 0,
            right: 0,
            child: _appBar,
          ),
        ],
      ),
    );
  }
}

Upvotes: 3

x23b5
x23b5

Reputation: 709

You could use a Stack, with your content and the App bar as children. For dismissing on scroll you can hide the app bar depending on the offset of your ScrollController or use an Animation.

Upvotes: 3

Related Questions