【问题标题】:Flutter Google Maps Detail Bottom Sheet using DraggableScrollableSheet & SliverAppBar?Flutter Google Maps Detail Bottom Sheet 使用 DraggableScrollableSheet 和 SliverAppBar?
【发布时间】:2019-10-28 14:59:06
【问题描述】:

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

这给了我(大部分)向上滚动时所需的效果,尽管我想知道如何在用户向下滚动时从缓慢降低其高度来实现 sliver 应用栏,最终在 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(),
          ],
        ),
      ),
    );
  }
}

任何想法/代码示例将不胜感激。

【问题讨论】:

    标签: flutter flutter-layout flutter-animation


    【解决方案1】:

    您想要达到的效果并不常见,因此可能很难找到一种优雅的方式来实现它。

    这是实现该效果的一种方法,在滚动时更改 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,
    

    【讨论】:

    • 感谢您的回答 - 效果很好,我认为它非常优雅。想知道作为后续你是否可以告诉我如何在 appbar 实际融入之前不显示 appbar 标题......换句话说,没有标题,只有视差图像,然后当用户向上滚动并且 appbar 启动只有融入视图,它才会在应用栏中显示标题。
    • 这更复杂,你可以用LayoutBuilder包裹FlexibleSpaceBar,并检查constraints.maxHeight是否小于显示标题的值,但是当底页靠近底部,因此您可能还需要检查 factor &gt;= 0.5,例如,标题可能是这样的:title: factor &gt;= 0.5 &amp;&amp; constraints.maxHeight &lt;= 100 ? Text('Hello World') : null,。使用LayoutBuilder 很昂贵,但我没有看到其他方法。
    猜你喜欢
    • 2021-06-10
    • 2022-12-08
    • 1970-01-01
    • 2022-10-18
    • 1970-01-01
    • 1970-01-01
    • 2019-06-13
    • 2021-08-12
    • 1970-01-01
    相关资源
    最近更新 更多