Flutter:如何允许内容与SliverAppBar重叠?

问题描述 投票:1回答:1

在android中,我们使用app:behavior_overlapTop="64dp"实现此目的

enter image description here

我希望重叠的内容像上面的GIF一样扑朔迷离

我的代码

class DetailsPage extends StatefulWidget {
  @override
  _DetailsPage createState() => _DetailsPage();
}

class _DetailsPage extends State<DetailsPage> {
  @override
  void initState() {
    super.initState();
    SystemChrome.setPreferredOrientations([
      DeviceOrientation.portraitUp,
      DeviceOrientation.portraitDown,
    ]);
    _scrollController = ScrollController();
    _scrollController.addListener(_scrollListener);

  }

  ScrollController _scrollController;

  bool lastStatus = true;

  _scrollListener() {
    if (isShrink != lastStatus) {
      setState(() {
        lastStatus = isShrink;
      });
    }
  }

  bool get isShrink {
    return _scrollController.hasClients &&
        _scrollController.offset > (250 - kToolbarHeight);
  }

  @override
  void dispose() {
    _scrollController.removeListener(_scrollListener);
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
//      backgroundColor: Colors.transparent,
      body: NestedScrollView(
        controller: _scrollController,
        headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
          return <Widget>[
            SliverAppBar(
              expandedHeight: 250.0,
              floating: false,
              brightness: Brightness.light,
              pinned: true,
//              elevation: 0.0,
//              backgroundColor: AppColors.colorCreateTripOrange,
              backgroundColor: Colors.white,
              actions: <Widget>[
                GestureDetector(
                  onTap: () {
                    Navigator.of(context).pop();
                  },
                  child: Padding(
                    padding: const EdgeInsets.only(right: 20.0),
                    child: Image.asset(
                      'assets/images/close.png',
                      width: 25.0,
                      height: 25.0,
                    ),
                  ),
                )
              ],
              leading: Padding(
                  padding: const EdgeInsets.only(left: 20.0, top: 0),
                  child: IconButton(
                    iconSize: 25,
                    icon: Image.asset(
                      'assets/images/back.png',
                      width: 25,
                      height: 25,
                    ),
                    color: Colors.black,
                    onPressed: () {
                      Navigator.of(context).pop();
                    },
                  )),
              flexibleSpace: FlexibleSpaceBar(
                  centerTitle: false,
                  collapseMode: CollapseMode.parallax,
                  title: Text(isShrink ? "Rome" : "",
                      style: TextStyle(
                        color: isShrink ? Colors.black : Colors.white,
                        fontFamily: 'bin_bold',
                        fontSize: 18.0,
                      )),
                  background: Image.network(
                    "https://media.istockphoto.com/photos/great-colosseum-rome-italy-picture-id692334500",
                    fit: BoxFit.cover,
                  )),
            ),

          ];
        },
        body: Container(
//          padding: const EdgeInsets.only(left: 20.0, right: 20.0, top: 40.0),
          decoration: BoxDecoration(
            color: AppColors.colorWhite,
            borderRadius: BorderRadius.all(Radius.circular(20)),
          ),
          child: Column(
            children: <Widget>[
              Expanded(
                child: Container(
                  padding:
                  const EdgeInsets.only(left: 20.0, right: 20.0, top: 40.0),
                  decoration: BoxDecoration(
                    color: AppColors.colorWhite,
                    borderRadius: BorderRadius.all(Radius.circular(20)),
                  ),
                  child: ListView(
                    children: <Widget>[
                      Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: <Widget>[
                          Padding(
                            padding: EdgeInsets.symmetric(horizontal: 15.0),
                            child: Text(
                              "Rome",
                              style: TextStyle(
                                  color: Colors.black,
                                  fontFamily: 'bin_bold',
                                  fontSize: 25.0),
                            ),
                          ),
                          Padding(
                            padding: EdgeInsets.only(top: 20, left: 15, right: 15),
                            child: Row(
                              children: <Widget>[
                                Image.asset(
                                  'assets/images/calender.png',
                                  width: 25.0,
                                  height: 25.0,
                                ),
                                Padding(
                                  padding: const EdgeInsets.only(left: 10.0),
                                  child: Text(
                                    "March 6-12, 2020",
                                    style: TextStyle(
                                        fontFamily: 'bin',
                                        fontSize: 18,
                                        color: AppColors.colorActivityGray),
                                  ),
                                )
                              ],
                            ),
                          ),
                          Container(
                            width: double.infinity,
                            margin: const EdgeInsets.only(
                                top: 20.0, left: 20.0, right: 30.0),
//                padding: const EdgeInsets.only(left: 20.0, right: 20.0),
                            decoration: BoxDecoration(
                              color: AppColors.colorTripsGray,
                              borderRadius: BorderRadius.all(Radius.circular(20)),
                              border: Border.all(color: AppColors.colorDivider),
                            ),
                            child: Column(
                              crossAxisAlignment: CrossAxisAlignment.start,
                              children: <Widget>[
                                Padding(
                                  padding: const EdgeInsets.only(
                                      top: 15.0,
                                      bottom: 0.0,
                                      left: 20.0,
                                      right: 20.0),
                                  child: Text(
                                    Constants.region,
                                    style: TextStyle(
                                        color: AppColors.colorLightBorderOrange,
                                        fontFamily: 'din',
                                        fontSize: 20),
                                  ),
                                ),
                                Padding(
                                  padding: const EdgeInsets.only(
                                      top: 10.0,
                                      bottom: 0.0,
                                      left: 20.0,
                                      right: 20.0),
                                  child: Text(
                                    Constants.firstName,
                                    style: TextStyle(
                                        color: AppColors.colorCreateGreyTrans,
                                        fontFamily: 'din',
                                        fontSize: 20),
                                  ),
                                ),
                                Padding(
                                  padding: const EdgeInsets.only(
                                      top: 10.0, bottom: 0.0, left: 0.0, right: 00.0),
                                  child: Divider(),
                                ),
                                Padding(
                                  padding: const EdgeInsets.only(
                                      top: 10.0,
                                      bottom: 0.0,
                                      left: 20.0,
                                      right: 20.0),
                                  child: Text(
                                    Constants.activities,
                                    style: TextStyle(
                                        color: AppColors.colorLightBorderOrange,
                                        fontFamily: 'din',
                                        fontSize: 20),
                                  ),
                                ),
                                Padding(
                                  padding: const EdgeInsets.only(
                                      top: 10.0,
                                      bottom: 0.0,
                                      left: 20.0,
                                      right: 20.0),
                                  child: Text(
                                    "Food & Bar, Must See Attractions",
                                    style: TextStyle(
                                        color: AppColors.colorCreateGreyTrans,
                                        fontFamily: 'din',
                                        fontSize: 20),
                                  ),
                                ),
                                Padding(
                                  padding: const EdgeInsets.only(
                                      top: 10.0, bottom: 0.0, left: 0.0, right: 00.0),
                                  child: Divider(),
                                ),
                                Padding(
                                  padding: const EdgeInsets.only(
                                      top: 10.0,
                                      bottom: 0.0,
                                      left: 20.0,
                                      right: 20.0),
                                  child: Text(
                                    Constants.noOfTravellers,
                                    style: TextStyle(
                                        color: AppColors.colorLightBorderOrange,
                                        fontFamily: 'din',
                                        fontSize: 20),
                                  ),
                                ),
                                Padding(
                                  padding: const EdgeInsets.only(
                                      top: 10.0,
                                      bottom: 0.0,
                                      left: 20.0,
                                      right: 20.0),
                                  child: Text(
                                    "2 Adults, 1 kid",
                                    style: TextStyle(
                                        color: AppColors.colorCreateGreyTrans,
                                        fontFamily: 'din',
                                        fontSize: 20),
                                  ),
                                ),
                                Padding(
                                  padding: const EdgeInsets.only(
                                      top: 10.0, bottom: 0.0, left: 0.0, right: 00.0),
                                  child: Divider(),
                                ),
                                Padding(
                                  padding: const EdgeInsets.only(
                                      top: 10.0,
                                      bottom: 0.0,
                                      left: 20.0,
                                      right: 20.0),
                                  child: Text(
                                    Constants.email,
                                    style: TextStyle(
                                        color: AppColors.colorLightBorderOrange,
                                        fontFamily: 'din',
                                        fontSize: 20),
                                  ),
                                ),
                                Padding(
                                  padding: const EdgeInsets.only(
                                      top: 10.0,
                                      bottom: 10.0,
                                      left: 20.0,
                                      right: 20.0),
                                  child: Text(
                                    "[email protected]",
                                    style: TextStyle(
                                        color: AppColors.colorCreateGreyTrans,
                                        fontFamily: 'din',
                                        fontSize: 20),
                                  ),
                                ),
                              ],
                            ),
                          ),
                        ],
                      )
                    ],
                  ),
                ),
              ),
              Container(
                width: double.infinity,
                margin: const EdgeInsets.only(top: 20.0),
                padding: const EdgeInsets.all(10.0),
                decoration: BoxDecoration(
                  color: AppColors.colorWhite,
                  borderRadius: BorderRadius.all(Radius.circular(40)),
                  border: Border.all(color: AppColors.colorDivider, width: 2.0),
                ),
                child: Center(
                  child: Wrap(
                    children: <Widget>[
                      MaterialButton(
                        padding: const EdgeInsets.symmetric(
                            horizontal: 40, vertical: 20),
                        textColor: Colors.black,
                        color: AppColors.colorWhite,
                        child: Text(
                          Constants.messageTripDesigner,
                          style: TextStyle(
                              fontFamily: 'din_bold',
                              fontSize: Constants.regionFontSize),
                        ),
                        shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(30.0),
                          side: BorderSide(
                              color: AppColors.colorLightBorderOrange,
                              width: 2),
                        ),
                        onPressed: () {
                          Navigator.of(context).pop();
                        },
                      )
                    ],
                  ),
                ),
              )
            ],
          ),
        ),
      ),
    );
  }
}


class MySliverAppBar extends SliverPersistentHeaderDelegate {
  final double expandedHeight;

  MySliverAppBar({@required this.expandedHeight});

  @override
  Widget build(
      BuildContext context, double shrinkOffset, bool overlapsContent) {
    return Stack(
      fit: StackFit.expand,
      overflow: Overflow.visible,
      children: [
        Image.network(
          "https://images.pexels.com/photos/396547/pexels-photo-396547.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
          fit: BoxFit.cover,
        ),
        Center(
          child: Opacity(
            opacity: shrinkOffset / expandedHeight,
            child: Text(
              "MySliverAppBar",
              style: TextStyle(
                color: Colors.white,
                fontWeight: FontWeight.w700,
                fontSize: 23,
              ),
            ),
          ),
        ),
      ],
    );
  }

  @override
  double get maxExtent => expandedHeight;

  @override
  double get minExtent => kToolbarHeight;

  @override
  bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) => true;
}

下面是我到目前为止尝试过的一些帖子

如果需要更多信息,请告诉我。提前致谢。您的努力将不胜感激。

android flutter dart flutter-layout flutter-animation
1个回答
© www.soinside.com 2019 - 2024. All rights reserved.