我在正文和底部导航栏中有一个博客文章列表。我想在帖子列表向下滚动时用向下滑动动画隐藏底部导航栏,并在向上滚动时用向上滑动动画显示。怎么做?
5 回答
此解决方案只是解决此问题的方法。可能会有一些不利的变化。
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) {
if(_isVisible)
setState(() {
_isVisible = false;
print("**** $_isVisible up");
});
}
if (_hideButtonController.position.userScrollDirection ==
ScrollDirection.forward) {
if(!_isVisible)
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
尝试将 ListView 包装为 NotificationListener 的子级并监听滚动事件 https://docs.flutter.io/flutter/widgets/OverscrollNotification-class.html
其他方法是使用 ScrollUpdateNotification https://docs.flutter.io/flutter/widgets/ScrollUpdateNotification-class.html
您需要一个 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)
)
],
),
),
);
}
}
屏幕截图(空安全):
代码:
使用的小部件是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'),
],
),
);
}
}
查看这个答案,=>底部导航滚动它使用动画来隐藏底部导航栏。您还可以自定义动画。