当用户向下滚动列表时,我试图隐藏底部的应用栏,就像行为部分的材料设计文档中显示的一样:
https://material.io/design/components/app-bars-bottom.html#behavior
到目前为止,我已经在Scaffold中添加了底部应用栏,但是它没有滚动行为。
在StackOverflow上也回答了类似的问题,但是它可以解决,并且已经在不久前得到了回答。
在Flutter中是否有达到这种效果的合法方法?
我的代码:
import 'package:fitness_fatality_flutter/data/entities/exercise.dart';
import 'package:fitness_fatality_flutter/data/entities/workout.dart';
import 'package:flutter/material.dart';
class WorkoutDetailsPage extends StatelessWidget {
Workout _workout = Workout();
final List<Exercise> exercises = [
Exercise(name: "Push Ups"),
Exercise(name: "Bench press"),
Exercise(name: "Pull ups"),
Exercise(name: "Press ups"),
Exercise(name: "Crunches"),
Exercise(name: "Sit ups"),
Exercise(name: "BIceps curl"),
Exercise(name: "Something else"),
Exercise(name: "Push Ups"),
Exercise(name: "Bench press"),
Exercise(name: "Pull ups"),
Exercise(name: "Press ups"),
Exercise(name: "Crunches"),
Exercise(name: "Sit ups"),
Exercise(name: "BIceps curl"),
Exercise(name: "Something else"),
Exercise(name: "Push Ups"),
Exercise(name: "Bench press"),
Exercise(name: "Pull ups"),
Exercise(name: "Press ups"),
Exercise(name: "Crunches"),
Exercise(name: "Sit ups"),
Exercise(name: "BIceps curl"),
Exercise(name: "Something else"),
Exercise(name: "Push Ups"),
Exercise(name: "Bench press"),
Exercise(name: "Pull ups"),
Exercise(name: "Press ups"),
Exercise(name: "Crunches"),
Exercise(name: "Sit ups"),
Exercise(name: "BIceps curl"),
Exercise(name: "Something else"),
Exercise(name: "Push Ups"),
Exercise(name: "Bench press"),
Exercise(name: "Pull ups"),
Exercise(name: "Press ups"),
Exercise(name: "Crunches"),
Exercise(name: "Sit ups"),
Exercise(name: "BIceps curl"),
Exercise(name: "Something else"),
];
WorkoutDetailsPage(this._workout);
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButtonAnimator: FloatingActionButtonAnimator.scaling,
floatingActionButtonLocation: FloatingActionButtonLocation.endDocked,
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.blue,
elevation: 12,
onPressed: () {},
),
bottomNavigationBar: BottomAppBar(
elevation: 8,
shape: CircularNotchedRectangle(),
color: Colors.blue,
child: Container(
height: 50,
child: Row(
children: <Widget>[Text("data")],
),
),
),
body: CustomScrollView(
slivers: <Widget>[
SliverAppBar(
bottom:BottomAppBar(), //<-- This would throw an error
expandedHeight: 150,
pinned: true,
floating: true,
snap: true,
flexibleSpace: FlexibleSpaceBar(
title: Text(_workout.name),
),
),
SliverList(
delegate: SliverChildBuilderDelegate(buildSliverListItem,
childCount: exercises.length),
),
],
),
);
}
Widget buildSliverListItem(BuildContext context, int index) {
return Center(
child: ListTile(
title: Text(exercises[index].name),
),
);
}
}
答案 0 :(得分:3)
BottomAppBar
是Scaffold
小部件的一部分,而不是Sliver
。有一种方法可以实现您描述的内容,但是有点复杂,并且需要StatefulWiget
和ScrollController
,AnimatedContainer
。请参阅下面的完整示例代码:
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: WorkoutDetailsPage(Workout()),
);
}
}
class Exercise {
String name;
Exercise({@required name}) {
this.name = name;
}
}
class Workout {
String name = "my name";
}
class WorkoutDetailsPage extends StatefulWidget {
Workout _workout = Workout();
WorkoutDetailsPage(this._workout);
@override
_WorkoutDetailsPageState createState() => _WorkoutDetailsPageState();
}
class _WorkoutDetailsPageState extends State<WorkoutDetailsPage> {
final List<Exercise> exercises = [
Exercise(name: "Push Ups"),
Exercise(name: "Bench press"),
Exercise(name: "Pull ups"),
Exercise(name: "Press ups"),
Exercise(name: "Crunches"),
Exercise(name: "Sit ups"),
Exercise(name: "BIceps curl"),
Exercise(name: "Something else"),
Exercise(name: "Push Ups"),
Exercise(name: "Bench press"),
Exercise(name: "Pull ups"),
Exercise(name: "Press ups"),
Exercise(name: "Crunches"),
Exercise(name: "Sit ups"),
Exercise(name: "BIceps curl"),
Exercise(name: "Something else"),
Exercise(name: "Push Ups"),
Exercise(name: "Bench press"),
Exercise(name: "Pull ups"),
Exercise(name: "Press ups"),
Exercise(name: "Crunches"),
Exercise(name: "Sit ups"),
Exercise(name: "BIceps curl"),
Exercise(name: "Something else"),
Exercise(name: "Push Ups"),
Exercise(name: "Bench press"),
Exercise(name: "Pull ups"),
Exercise(name: "Press ups"),
Exercise(name: "Crunches"),
Exercise(name: "Sit ups"),
Exercise(name: "BIceps curl"),
Exercise(name: "Something else"),
Exercise(name: "Push Ups"),
Exercise(name: "Bench press"),
Exercise(name: "Pull ups"),
Exercise(name: "Press ups"),
Exercise(name: "Crunches"),
Exercise(name: "Sit ups"),
Exercise(name: "BIceps curl"),
Exercise(name: "Something else"),
];
ScrollController _hideButtonController;
bool _isVisible = true;
@override
void initState() {
super.initState();
_isVisible = true;
_hideButtonController = new ScrollController();
_hideButtonController.addListener(() {
print("listener");
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 Scaffold(
floatingActionButtonAnimator: FloatingActionButtonAnimator.scaling,
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: _isVisible
? FloatingActionButton(
backgroundColor: Colors.blue,
elevation: 12,
onPressed: () {},
)
: null,
bottomNavigationBar: AnimatedContainer(
duration: Duration(milliseconds: 200),
height: _isVisible ? 60 : 0.0,
child: BottomAppBar(
elevation: 8,
shape: CircularNotchedRectangle(),
color: Colors.blue,
child: Container(
height: 60,
child: Row(
children: <Widget>[Text("data")],
),
),
),
),
body: CustomScrollView(
controller: _hideButtonController,
slivers: <Widget>[
SliverAppBar(
expandedHeight: 150,
pinned: true,
floating: true,
snap: true,
flexibleSpace: FlexibleSpaceBar(
title: Text(widget._workout.name),
),
),
SliverList(
delegate: SliverChildBuilderDelegate(buildSliverListItem,
childCount: exercises.length),
),
],
),
);
}
Widget buildSliverListItem(BuildContext context, int index) {
return Center(
child: ListTile(
title: Text(exercises[index].name),
),
);
}
}