简体   繁体   中英

Flutter SliverList Overlap on SliverAppBar

I'm trying to overlap a SliverList a few pixels over the SliverAppBar . I'd like the image in the FlexibleSpaceBar to go under the radius of my SliverList . I can only get the radius. Without the ability to overlap the SliverList onto the SliverAppBar . 在此处输入图像描述

return CustomScrollView(
      physics: BouncingScrollPhysics(),
      slivers: [
        SliverAppBar(
          backgroundColor: Colors.transparent,
          elevation: 0.0,
          expandedHeight: getProportionateScreenHeight(350),
          automaticallyImplyLeading: false,
          pinned: true,
          stretch: true,
          leading: Container(
            padding: EdgeInsets.fromLTRB(8.0, 8.0, 0.0, 0.0),
            child: SizedBox(
              height: getProportionateScreenWidth(40),
              width: getProportionateScreenWidth(40),
              child: FlatButton(
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(60),
                ),
                color: Colors.white,
                padding: EdgeInsets.zero,
                child: Icon(Icons.arrow_back_ios),
                onPressed: () => Navigator.pop(context),
              ),
            ),
          ),
          actions: <Widget>[
            Container(
              padding: EdgeInsets.fromLTRB(0.0, 8.0, 8.0, 0.0),
              child: SizedBox(
                height: getProportionateScreenWidth(40),
                width: getProportionateScreenWidth(40),
                child: FlatButton(
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(60),
                  ),
                  color: Colors.white,
                  padding: EdgeInsets.zero,
                  child: Icon(Icons.more_vert),
                  onPressed: () {}
                ),
              ),
            ),
          ],
          flexibleSpace: FlexibleSpaceBar(
            //title: Text(_event.Title),
            centerTitle: true,
            stretchModes: [
              StretchMode.zoomBackground
            ],
            background: Stack(
              fit: StackFit.expand,
              children: <Widget>[
                Image.asset('assets/images/events/sunset.jpg', fit: BoxFit.cover),
                DecoratedBox(
                  decoration: BoxDecoration(
                    gradient: LinearGradient(
                      begin: Alignment(0.0, 0.5),
                      end: Alignment(0.0, 0.0),
                      colors: <Color>[
                        Color(0x60000000),
                        Color(0x00000000),
                      ],
                    ),
                  ),
                ),
              ]
            )
          )
        ),
        SliverList(
          delegate: SliverChildListDelegate([
            Column(
              children: [
                Container(
                  padding: EdgeInsets.only(top: getProportionateScreenHeight(20), bottom: getProportionateScreenHeight(100)),
                  child: EventDescription(event: _event),
                  decoration: BoxDecoration(
                    color: Color(0xFFF5F6F9),
                    borderRadius: BorderRadius.only(
                      topLeft: Radius.circular(40),
                      topRight: Radius.circular(40),
                    ),
                    boxShadow: [
                      BoxShadow(
                        color: Colors.grey.withOpacity(0.5),
                        spreadRadius: 5,
                        blurRadius: 7,
                        offset: Offset(0, 0), // changes position of shadow
                      ),
                    ],
                  )
                ),
              ],
            )
          ]),
        )
      ]
    );

Would you like to use a workaround solution? My solution is put the top part of the SliverList inside SliverAppBar .

The only problem is that the fade out animation of flexiable space (while scrolling down) do effect to the top bar. (Because it is in the flexibleSpace )

Due to SliverAppBar elevation is higher than SliverList . Any Scale or Translate to the widget always get the opposite result from your expected (SliverAppBar overlap on SliverList).

I use stack to put the top part inside FlexibleSpaceBar, set collapseMode to CollapseMode.pin and set alignment to Alignment.bottomCenter :

SliverAppBar(
  ...
  flexibleSpace: FlexibleSpaceBar(
    collapseMode: CollapseMode.pin,
    ...
    background: Stack(
      ...
      children: [
        ...
        Align(
          alignment: Alignment.bottomCenter,
          child: Container(
            child: Container(
              height: _height, // 40
            ),
            decoration: BoxDecoration(
              color: Color(0xFFF5F6F9),
              borderRadius: BorderRadius.only(
                topLeft: Radius.circular(40),
                topRight: Radius.circular(40),
              ),
              boxShadow: [
                BoxShadow(
                  color: Colors.grey.withOpacity(0.5),
                  spreadRadius: 5,
                  blurRadius: 7,
                  offset: Offset(0, 0), // changes position of shadow
                ),
              ],
            ),
          ),
        ),
      ]
     ...

If you need to use collapseMode: CollapseMode.parallax like the default setting do, the _height need to be dynamical during scrolling.

void initState(){
  _scrollController = ScrollController()..addListener(() {
    setState(() {
      _height = math.max(_scrollController.offset*_topBarFactor +_topBarHeight,_topBarHeight);
    });
}
});

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM