Sliver Stack in Flutter

💜Dabo (개발자 다보)·2024년 1월 25일
0
post-thumbnail

Goal

Converting the Widget version of the code to the Sliver version of the code

Widget Vesrion:

return Scaffold(
  body: Stack(
    children: [
      ListView.builder(
        itemBuilder: (context, index) => ListTile(
          title: Text(
            'under layer $index',
          ),
        ),
        itemCount: 100,
      ),
      Positioned(
        bottom: 0,
        child: Container(
          width: MediaQuery.of(context).size.width,
          height: 80,
          color: Colors.yellow,
          child: const Text('overlay layer'),
        ),
      ),
    ],
  ),
);

Sliver Version:

No default widget called Sliver Stack

return Scaffold(
  body: CustomScrollView(
    slivers: [
		// ???: Sliver Stack
      SliverList.builder(
        itemBuilder: (context, index) => ListTile(
          title: Text(
            'under layer $index',
          ),
        ),
        itemCount: 100,
      ),
    ],
  ),
);

???


try1

1. used package: sliver_tools

https://pub.dev/packages/sliver_tools

2. use SliverStack with the sliver_tools package

example code: (link)

class WidgetThatReturnsASliver extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return SliverStack(
      insetOnOverlap: false, // defaults to false
      children: <Widget>[
        SliverPositioned.fill(
          child: Container(
            decoration: BoxDecoration(
              color: Colors.white,
              boxShadow: const <BoxShadow>[
                BoxShadow(
                  offset: Offset(0, 4),
                  blurRadius: 8,
                  color: Colors.black26,
                )
              ],
              borderRadius: BorderRadius.circular(8),
            ),
          ),
        ),
        SliverList(...),
      ],
    );
  }
}

Results of use example code:

return Scaffold(
  body: CustomScrollView(
    slivers: [
      SliverStack(
        children: [
          SliverList.builder(
            itemBuilder: (context, index) => ListTile(
              title: Text(
                'under layer $index',
              ),
            ),
            itemCount: 100,
          ),
          SliverPositioned.fill(
            child: Container(
              decoration: BoxDecoration(
                color: Colors.yellow,
                borderRadius: BorderRadius.circular(8),
              ),
            ),
          ),
        ],
      ),
    ],
  ),
);

Oka...a..yyyyyy...

I see it overlays, but I don't want it to be a fill,
I want it to be placed at the bottom by 80 height.

3. SliverPositioned fill to bottom

Remove fill and make it bottom: 0 from SliverPositioned

Code:

return Scaffold(
  body: CustomScrollView(
    slivers: [
      SliverStack(
        children: [
          ...,
          SliverPositioned(
            bottom: 0,
            child: Container(
              decoration: BoxDecoration(
                color: Colors.yellow,
                borderRadius: BorderRadius.circular(8),
              ),
              child: const Text('overlay layer'),
            ),
          ),
        ],
      ),
    ],
  ),
);

Result:

It doesn't overlay on top of the screen like Stack does.
It overlays on top of all drawn widgets of any length in Sliver.


try2

1. Similar problem found on stackoverflow

https://stackoverflow.com/questions/68860119/how-to-make-a-widget-to-be-on-the-bottom-of-the-screen-if-using-sliverstack

SliverFillRemaining(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        children: [
          _buildRedBox(),
        ],
      ),
    ),

2. Applied Results

code:

return Scaffold(
  body: CustomScrollView(
    slivers: [
      SliverStack(
        children: [
          SliverList.builder(
            itemBuilder: (context, index) => ListTile(
              title: Text(
                'under layer $index',
              ),
            ),
            itemCount: 100,
          ),
          SliverFillRemaining(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.end,
              children: [
                Container(
                  decoration: BoxDecoration(
                    color: Colors.yellow,
                    borderRadius: BorderRadius.circular(8),
                  ),
                  child: const Text('overlay layer'),
                )
              ],
            ),
          ),
        ],
      ),
    ],
  ),
);

Result:


try3

1. Similar problem found on stackoverflow .. 2 😁

https://stackoverflow.com/questions/67305872/how-to-add-a-fixed-to-bottom-container-to-a-sliver-flutter

2. Applied Results

code:

return Scaffold(
  body: CustomScrollView(
    slivers: [
      SliverStack(
        children: [
          SliverList.builder(
            itemBuilder: (context, index) => ListTile(
              title: Text(
                'under layer $index',
              ),
            ),
            itemCount: 100,
          ),
        ],
      ),
    ],
  ),
  bottomNavigationBar: Container(
    decoration: BoxDecoration(
      color: Colors.yellow,
      borderRadius: BorderRadius.circular(8),
    ),
    child: const Text('overlay layer'),
  ),
);

Result:


Oh.. 이게되네..
Why didn't I think of this...


Result

Instead of using SliverStack, you can use Scaffold's bottomNavigationBar property to anchor the bottom.

code:

return Scaffold(
  body: CustomScrollView(
    slivers: [
      SliverStack(
        children: [
          SliverList.builder(
            itemBuilder: (context, index) => ListTile(
              title: Text(
                'under layer $index',
              ),
            ),
            itemCount: 100,
          ),
        ],
      ),
    ],
  ),
  bottomNavigationBar: Container(
    height: 80,
    decoration: BoxDecoration(
      color: Colors.yellow,
      borderRadius: BorderRadius.circular(8),
    ),
    child: const Text('overlay layer'),
  ),
);
profile
𝙸 𝚊𝚖 𝚊 𝚌𝚞𝚛𝚒𝚘𝚞𝚜 𝚍𝚎𝚟𝚎𝚕𝚘𝚙𝚎𝚛 𝚠𝚑𝚘 𝚎𝚗𝚓𝚘𝚢𝚜 𝚍𝚎𝚏𝚒𝚗𝚒𝚗𝚐 𝚊 𝚙𝚛𝚘𝚋𝚕𝚎𝚖. 🇰🇷👩🏻‍💻

0개의 댓글

관련 채용 정보