使用 DraggableScrollableSheet 和 SliverAppBar 的 Flutter Google Maps Detail Bottom Sheet?

Flutter Google Maps Detail Bottom Sheet using DraggableScrollableSheet & SliverAppBar?

我正在尝试使用 Flutter 重新创建 Google 地图详细信息底部 sheet 的功能。我正在使用 DraggableScrollableSheet 以及 CustomScrollViewSliverAppbar(尽管我很乐意使用其他方法)。

这给了我(大部分)向上滚动时的预期效果,尽管我想知道如何在用户向下滚动时慢慢降低其高度,最终 '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,