how to add Positioned stack inside SliverList and make it scrollable , like when we scroll the top image part will hide and only see appBar&scroll

244 views Asked by At

here i am pasting the video link i want to achieve , please helphi here i want to add a container at the top of the scrollable side and also some part of the container should be at the end of app bar and it should be scrollable

class HomePage extends StatelessWidget {
  const HomePage({super.key});
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomScrollView(
        slivers: <Widget>[
          SliverAppBar(
            leading:IconButton(onPressed: (){},
              icon:const Icon(Icons.arrow_back) ,
              color: Colors.white,
            ),
            actions: [
              Align(
                alignment: Alignment.centerLeft,
                child: IconButton(onPressed: (){},
                  icon:const Icon(Icons.notifications_none_outlined) ,
                  color: Colors.white,
                ),
              ),
              Align(
                alignment: Alignment.centerLeft,
                child: IconButton(onPressed: (){},
                  icon:const Icon(Icons.more_vert_outlined) ,
                  color: Colors.white,
                ),
              ),
            ],
            backgroundColor: ThemeManager.sliverAppBarColor,
            expandedHeight: 350.0,
            pinned: true,
            flexibleSpace: FlexibleSpaceBar(
              background: Padding(
                padding:  const EdgeInsets.symmetric(horizontal: 20.0),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.center,
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    const SizedBox(height: 60,),
                    ClipOval(
                      child: Container(
                        child: Image.asset(
                          '',
                          fit: BoxFit.cover,
                          width: 120,
                          height: 120,
                        ),
                      ),
                    ),
                    const Text('',
                    style: TextStyle(color: ThemeManager.profileNameTextColor,
                      fontSize: 24,
                      fontWeight: FontWeight.w600,
                    ),),
                    const Center(
                      child: Text('',
                        style: TextStyle(color:
                        ThemeManager.profileNameTextColor,
                          fontSize: 16,
                          fontWeight: FontWeight.w400,
                        ),

                      ),
                    ),
                    const SizedBox(height: 3,),
                    // const EmployeeIdContainer(),
                    const SizedBox(height: 8,),
                    const SizedBox(height: 10,),
                    const SizedBox(height: 10,),
                  ],
                ),
              ),
            ),
          ),
          SliverList(
            delegate: SliverChildBuilderDelegate(
                  (BuildContext context, int index) {
                    return Stack(
                      children: [
                        Positioned(
                          top:-10,
                          left: 0,
                          right: 0,
                          bottom: 0,
                          child: Container(
                            width: 400,
                            height: 500,
                          ),
                        ),
                      ],
                    );
              },
              childCount: 50, // Number of list items
            ),
          ),
        ],
      ),
    );
  }
}

here i want to acheive is when we scroll the appbar the scollable container top end must be in FlexibleSpaceBar means the container should be stacked in top -10 position.

1

There are 1 answers

0
Md. Yeasin Sheikh On

You can use SliverPersistentHeaderDelegate and little math for visualization.

final double bottom = lerpDouble(-100, 10, shrinkOffset / expandedHeight)!;

Here is the snippet

class AppSliverPersistentHeaderDelegate extends SliverPersistentHeaderDelegate {
  AppSliverPersistentHeaderDelegate({
    required this.expandedHeight,
  });

  final double expandedHeight;

  @override
  Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
    final double bottom = lerpDouble(-100, 10, shrinkOffset / expandedHeight)!; // play with your values here
    return ColoredBox(
      // you may use ImageFilter instead
      color: Colors.red.withOpacity(.1),
      child: Stack(
        clipBehavior: Clip.none,
        children: [
          Positioned(
            left: 0,
            right: 0,
            bottom: bottom,
            child: Placeholder(
              //replace with image and increase height>maxExtent
              fallbackHeight: maxExtent * 1.5,
            ),
          ),
          Align(
            alignment: Alignment.topCenter,
            child: Container(
              height: kToolbarHeight,
              color: Colors.deepPurple.withAlpha(100),
              alignment: Alignment.center,
              child: Text('Title'),
            ),
          ),
        ],
      ),
    );
  }

  @override
  double get maxExtent => expandedHeight;

  @override
  double get minExtent => kToolbarHeight;

  @override
  bool shouldRebuild(covariant AppSliverPersistentHeaderDelegate oldDelegate) => oldDelegate.expandedHeight != expandedHeight;
}

And use

slivers: [
  SliverPersistentHeader(
    pinned: true,
    delegate: AppSliverPersistentHeaderDelegate(expandedHeight: 200),
  ),

Initial look

enter image description here

And on scroll

enter image description here