在Flutter中的Scroll上隐藏底部导航栏

时间:2018-05-15 15:09:01

标签: flutter flutter-layout

我在正文和底部导航栏中有一个博客帖子列表。我希望在向下滚动帖子列表时使用向下滑动动画隐藏底部导航栏,并在向上滚动时使用向上滑动动画显示。怎么做?

5 个答案:

答案 0 :(得分:1)

尝试将ListView包装为NotificationListener的子节点并侦听滚动事件 https://docs.flutter.io/flutter/widgets/OverscrollNotification-class.html

其他方法是使用ScrollUpdateNotification https://docs.flutter.io/flutter/widgets/ScrollUpdateNotification-class.html

答案 1 :(得分:1)

此解决方案只是解决此问题的方法。 可能会有一些不利的变化。

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

void main() {
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  ScrollController _hideButtonController;

  var _isVisible;
  @override
  initState() {
    super.initState();
    _isVisible = true;
    _hideButtonController = new ScrollController();
    _hideButtonController.addListener(() {
      if (_hideButtonController.position.userScrollDirection ==
          ScrollDirection.reverse) {
        setState(() {
          _isVisible = false;
          print("**** $_isVisible up");
        });
      }
      if (_hideButtonController.position.userScrollDirection ==
          ScrollDirection.forward) {
        setState(() {
          _isVisible = true;
          print("**** $_isVisible down");
        });
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: new Center(
          child: new CustomScrollView(
        controller: _hideButtonController,
        shrinkWrap: true,
        slivers: <Widget>[
          new SliverPadding(
            padding: const EdgeInsets.all(20.0),
            sliver: new SliverList(
              delegate: new SliverChildListDelegate(
                <Widget>[
                  const Text('I\'m dedicating every day to you'),
                  const Text('Domestic life was never quite my style'),
                  const Text('When you smile, you knock me out, I fall apart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('And I thought I was so smart'),
                  const Text('I realize I am crazy'),
                ],
              ),
            ),
          ),
        ],
      )),
      bottomNavigationBar: AnimatedContainer(
        duration: Duration(milliseconds: 500),
        height: _isVisible ? 60.0 : 0.0,
        child: _isVisible
            ? new BottomNavigationBar(
                type: BottomNavigationBarType.fixed,
                items: [
                  new BottomNavigationBarItem(
                    icon: Icon(Icons.home),
                    title: Text('Home'),
                  ),
                  new BottomNavigationBarItem(
                    icon: Icon(Icons.card_giftcard),
                    title: Text('Offers'),
                  ),
                  new BottomNavigationBarItem(
                    icon: Icon(Icons.account_box),
                    title: Text('Account'),
                  ),
                ],
                currentIndex: 0,

              )
            : Container(
                color: Colors.white,
                width: MediaQuery.of(context).size.width,
              ),
      ),

    );
  }

}

您还可以在此使用条形条:-

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

void main() {
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  ScrollController _hideButtonController;

  var _isVisible;
  @override
  initState() {
    super.initState();
    _isVisible = true;
    _hideButtonController = new ScrollController();
    _hideButtonController.addListener(() {
      if (_hideButtonController.position.userScrollDirection ==
          ScrollDirection.reverse) {
        setState(() {
          _isVisible = false;
          print("**** $_isVisible up");
        });
      }
      if (_hideButtonController.position.userScrollDirection ==
          ScrollDirection.forward) {
        setState(() {
          _isVisible = true;
          print("**** $_isVisible down");
        });
      }
    });
  }

  final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
  TextEditingController searchController = new TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      resizeToAvoidBottomPadding: true,
      drawer: Container(),
      key: scaffoldKey,
      body: NestedScrollView(
        controller: _hideButtonController,
        headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
          return <Widget>[
            SliverAppBar(
              title: Container(
                child: Card(
                  elevation: 3.0,
                  margin: EdgeInsets.only(top: 10.0),
                  shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.all(Radius.circular(2.0))),
                  child: Padding(
                    padding: EdgeInsets.symmetric(horizontal: 15.0),
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: <Widget>[
                        GestureDetector(
                          child: Icon(
                            Icons.sort,
                            color: Colors.black54,
                          ),
                          onTap: () {
                            scaffoldKey.currentState.openDrawer();
                          },
                        ),
                        SizedBox(
                          width: 10.0,
                        ),
                        Expanded(
                          child: TextField(
                            controller: searchController,
                            decoration: InputDecoration(
                                border: InputBorder.none,
                                hintText: "What are you looking for?"),
                          ),
                        ),
                        GestureDetector(
                          onTap: () {
                            searchController.clear();
                          },
                          child: Icon(
                            Icons.clear,
                            color: Colors.black54,
                          ),
                        ),
                      ],
                    ),
                  ),
                ),
              ),
              elevation: 10.0,
              automaticallyImplyLeading: false,
              expandedHeight: 70,
              floating: true,
              snap: true,
            )
          ];
        },
        body: new ListView(
          children: <Widget>[
            const Text('I\'m dedicating every day to you'),
            const Text('Domestic life was never quite my style'),
            const Text('When you smile, you knock me out, I fall apart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('I realize I am crazy'),
            const Text('I\'m dedicating every day to you'),
            const Text('Domestic life was never quite my style'),
            const Text('When you smile, you knock me out, I fall apart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('And I thought I was so smart'),
            const Text('I realize I am crazy'),
          ],
        ),
      ),

      bottomNavigationBar: AnimatedContainer(
        duration: Duration(seconds: 1),
        height: _isVisible ? 60.0 : 0.0,
        child: _isVisible
            ? AnimatedContainer(
                duration: Duration(milliseconds: 200),
                height: _isVisible ? 60.0 : 0.0,
                child: _isVisible
                    ? new BottomNavigationBar(
                        type: BottomNavigationBarType.fixed,
                        items: [
                          new BottomNavigationBarItem(
                            icon: Icon(Icons.home),
                            title: Text('Home'),
                          ),
                          new BottomNavigationBarItem(
                            icon: Icon(Icons.card_giftcard),
                            title: Text('Offers'),
                          ),
                          new BottomNavigationBarItem(
                            icon: Icon(Icons.account_box),
                            title: Text('Account'),
                          ),
                        ],
                        currentIndex: 0,
                      )
                    : Container(
                        color: Colors.white,
                        width: MediaQuery.of(context).size.width,
                      ),
              )
            : Container(
                color: Theme.of(context).primaryColor,
                width: MediaQuery.of(context).size.width,
              ),
      ),

//                _isVisible
//                  ? bottomNavigationBar()
//                  : Container(
//                      height: 0.0,
//                      width: MediaQuery.of(context).size.width,
//                    ),
    );
  }
}

请评论您对此代码的看法,以便我们改进此代码。

这是从这个答案中摘下来的: Flutter - Hiding FloatingActionButton

答案 2 :(得分:1)

屏幕截图(空安全):

enter image description here


代码:

使用的小部件是 StatelessWidget,因此不必担心多次调用 setState

创建这个类:

class ScrollListener extends ChangeNotifier {
  double bottom = 0;
  double _last = 0;

  ScrollListener.initialise(ScrollController controller, [double height = 56]) {
    controller.addListener(() {
      final current = controller.offset;
      bottom += _last - current;
      if (bottom <= -height) bottom = -height;
      if (bottom >= 0) bottom = 0;
      _last = current;
      if (bottom <= 0 && bottom >= -height) notifyListeners();
    });
  }
}

用法:

class MyPage extends StatelessWidget {
  final ScrollController _controller = ScrollController();
  final double _bottomNavBarHeight = 56;
  late final ScrollListener _model;

  MyPage() {
    _model = ScrollListener.initialise(_controller);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: AnimatedBuilder(
        animation: _model,
        builder: (context, child) {
          return Stack(
            children: [
              ListView.builder(
                controller: _controller,
                itemCount: 20,
                itemBuilder: (_, i) => ListTile(title: Text('Item $i')),
              ),
              Positioned(
                left: 0,
                right: 0,
                bottom: _model.bottom,
                child: _bottomNavBar,
              ),
            ],
          );
        },
      ),
    );
  }

  Widget get _bottomNavBar {
    return SizedBox(
      height: _bottomNavBarHeight,
      child: BottomNavigationBar(
        backgroundColor: Colors.amber[800],
        items: [
          BottomNavigationBarItem(icon: Icon(Icons.call), label: 'Call'),
          BottomNavigationBarItem(icon: Icon(Icons.message), label: 'Message'),
        ],
      ),
    );
  }
}

答案 3 :(得分:0)

您需要一个ScrollController来监视/观察Listview的滚动方向。控制器将在initState中初始化,并向其添加一个侦听器...。侦听器应根据滚动方向切换一个布尔值...。然后,底部Naigatio Bar底部应使用OffStage包裹

此代码应提供帮助


import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  bool _isVisible = true;
  ScrollController controller;


  @override
  void initState() {
    super.initState();
    controller = ScrollController();
    controller.addListener(() {
      setState(() {
        _isVisible = controller.position.userScrollDirection == ScrollDirection.forward;
      });
    });
  }



  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ListView(
        controller: controller,
        children: List.generate(200, (index) => Text(("$index"))),
      ),
      bottomNavigationBar: Offstage(
        offstage: !_isVisible,
        child: BottomNavigationBar(
          items: [
            BottomNavigationBarItem(
              title: Text("Hello"),
              icon: Icon(Icons.style)
            ),
            BottomNavigationBarItem(
                title: Text("Hi"),
                icon: Icon(Icons.style)
            ),
            BottomNavigationBarItem(
                title: Text("Hey"),
                icon: Icon(Icons.style)
            )
          ],
        ),
      ),
    );
  }
}

答案 4 :(得分:0)

查看此答案== Bottom Navigation Scrolling,它使用动画隐藏底部导航栏。您还可以自定义动画。