使用 DraggableScrollableSheet 和 SliverAppBar 的 Flutter Google Maps Detail Bottom Sheet?
Flutter Google Maps Detail Bottom Sheet using DraggableScrollableSheet & SliverAppBar?
我正在尝试使用 Flutter 重新创建 Google 地图详细信息底部 sheet 的功能。我正在使用 DraggableScrollableSheet
以及 CustomScrollView
和 SliverAppbar
(尽管我很乐意使用其他方法)。
这给了我(大部分)向上滚动时的预期效果,尽管我想知道如何在用户向下滚动时慢慢降低其高度,最终 'hiding' 它一旦 minChildSize 在 DraggableScrollableSheet
上为 'hit'
这是我当前的代码(为简单起见进行了精简)。
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
AnimationController _controllerDetails;
Tween<Offset> _tween = Tween(begin: Offset(0, 1), end: Offset(0, 0));
@override
void initState() {
super.initState();
_controllerDetails = AnimationController(
vsync: this, duration: const Duration(milliseconds: 500));
}
bool _onScrollDetails(Notification notification) {
return true;
}
@override
void dispose() {
_controllerDetails.dispose();
super.dispose();
}
void _showDetails() async {
if (_controllerDetails.isDismissed) {
_controllerDetails.forward();
} else if (_controllerDetails.isCompleted) {
_controllerDetails.reverse();
}
}
Widget _buildDetails() {
return SizedBox.expand(
child: SlideTransition(
position: _tween.animate(_controllerDetails),
child: DraggableScrollableActuator(
child: NotificationListener(
onNotification: _onScrollDetails,
child: DraggableScrollableSheet(
minChildSize: 0.1,
initialChildSize: 0.3,
builder:
(BuildContext context, ScrollController scrollController) {
return Container(
child: CustomScrollView(
controller: scrollController,
slivers: <Widget>[
SliverAppBar(
expandedHeight: 200,
pinned: true,
floating: true,
flexibleSpace: FlexibleSpaceBar(
title: Text('Hello World'),
background: Image.network(
"https://images.pexels.com/photos/396547/pexels-photo-396547.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
fit: BoxFit.cover,
)),
),
SliverFillRemaining(
child: Text(
"Once the draggable sheet goes below some value (like 0.6) how can i 'parallax' reduce the expandedHeight of the sliverAppBar, then increasing it again as the user scrolls up..."),
)
],
),
);
},
),
),
),
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: GestureDetector(
child: FloatingActionButton(
child: AnimatedIcon(
icon: AnimatedIcons.menu_close, progress: _controllerDetails),
elevation: 5,
onPressed: _showDetails,
),
),
body: SizedBox.expand(
child: Stack(
children: <Widget>[
_buildDetails(),
],
),
),
);
}
}
任何想法/代码示例将不胜感激。
您尝试实现的效果不常见,因此可能很难找到一种优雅的方法来实现。
这是实现该效果的一种方法,在滚动时更改 expandedHeight
属性:
// in the builder of DraggableScrollableSheet
double factor = scrollController.hasClients ? scrollController.position.viewportDimension / MediaQuery.of(context).size.height : 0;
// then in the SliverAppBar
expandedHeight: 200 * factor,
我正在尝试使用 Flutter 重新创建 Google 地图详细信息底部 sheet 的功能。我正在使用 DraggableScrollableSheet
以及 CustomScrollView
和 SliverAppbar
(尽管我很乐意使用其他方法)。
这给了我(大部分)向上滚动时的预期效果,尽管我想知道如何在用户向下滚动时慢慢降低其高度,最终 'hiding' 它一旦 minChildSize 在 DraggableScrollableSheet
这是我当前的代码(为简单起见进行了精简)。
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
AnimationController _controllerDetails;
Tween<Offset> _tween = Tween(begin: Offset(0, 1), end: Offset(0, 0));
@override
void initState() {
super.initState();
_controllerDetails = AnimationController(
vsync: this, duration: const Duration(milliseconds: 500));
}
bool _onScrollDetails(Notification notification) {
return true;
}
@override
void dispose() {
_controllerDetails.dispose();
super.dispose();
}
void _showDetails() async {
if (_controllerDetails.isDismissed) {
_controllerDetails.forward();
} else if (_controllerDetails.isCompleted) {
_controllerDetails.reverse();
}
}
Widget _buildDetails() {
return SizedBox.expand(
child: SlideTransition(
position: _tween.animate(_controllerDetails),
child: DraggableScrollableActuator(
child: NotificationListener(
onNotification: _onScrollDetails,
child: DraggableScrollableSheet(
minChildSize: 0.1,
initialChildSize: 0.3,
builder:
(BuildContext context, ScrollController scrollController) {
return Container(
child: CustomScrollView(
controller: scrollController,
slivers: <Widget>[
SliverAppBar(
expandedHeight: 200,
pinned: true,
floating: true,
flexibleSpace: FlexibleSpaceBar(
title: Text('Hello World'),
background: Image.network(
"https://images.pexels.com/photos/396547/pexels-photo-396547.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
fit: BoxFit.cover,
)),
),
SliverFillRemaining(
child: Text(
"Once the draggable sheet goes below some value (like 0.6) how can i 'parallax' reduce the expandedHeight of the sliverAppBar, then increasing it again as the user scrolls up..."),
)
],
),
);
},
),
),
),
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: GestureDetector(
child: FloatingActionButton(
child: AnimatedIcon(
icon: AnimatedIcons.menu_close, progress: _controllerDetails),
elevation: 5,
onPressed: _showDetails,
),
),
body: SizedBox.expand(
child: Stack(
children: <Widget>[
_buildDetails(),
],
),
),
);
}
}
任何想法/代码示例将不胜感激。
您尝试实现的效果不常见,因此可能很难找到一种优雅的方法来实现。
这是实现该效果的一种方法,在滚动时更改 expandedHeight
属性:
// in the builder of DraggableScrollableSheet
double factor = scrollController.hasClients ? scrollController.position.viewportDimension / MediaQuery.of(context).size.height : 0;
// then in the SliverAppBar
expandedHeight: 200 * factor,