slivertoboxadapter goes under sliverpersistentheader

152 views Asked by At

SliverPersistentHeader Should go behind SliverBoxToAdapter

Here is the result which i got

SliverBoxToAdapter goes under SliverPersistentHeader while I scroll. What I need is for SliverPersistentHeader to go behind SliverBoxToAdapter while I scroll. I have tried using NestedScrollView as well, but I didn't get any results that match my requirements.

here is the video

import 'dart:ui';
import 'package:flutter/material.dart';

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.transparent,
      body: Material(
        elevation: 0.8,
        color: Colors.black,
        child: BackdropFilter(
          filter: ImageFilter.blur(sigmaX: 13, sigmaY: 13),
          child: ScrollConfiguration(
            behavior: const ScrollBehavior().copyWith(overscroll: false),
            child: CustomScrollView(
              slivers: [
                buildSliverPersistentHeader(context),
                buildSliverToBoxAdapter(),
              ],
            ),
          ),
        ),
      ),
    );
  }

  SliverPersistentHeader buildSliverPersistentHeader(BuildContext context) {
    return SliverPersistentHeader(
      pinned: true,
      floating: true,
      delegate: Widget1(
        max: MediaQuery.of(context).size.height * 0.75,
        min: MediaQuery.of(context).size.height * 0.5,
      ),
    );
  }

  SliverToBoxAdapter buildSliverToBoxAdapter() {
    return SliverToBoxAdapter(
      child: ScrollConfiguration(
        behavior: const ScrollBehavior().copyWith(overscroll: false),
        child: Container(
            decoration: const BoxDecoration(
              color: Colors.white,
              borderRadius: BorderRadius.only(
                topLeft: Radius.circular(23),
                topRight: Radius.circular(23),
              ),
            ),
            padding: const EdgeInsets.symmetric(horizontal: 16),
            child: Container(
              height: 700,
              width: MediaQuery.of(context).size.width,
              color: Colors.red,
            )),
      ),
    );
  }
}

class Widget1 extends SliverPersistentHeaderDelegate {
  double max;
  double min;
  Widget1({
    required this.max,
    required this.min,
  });

  @override
  Widget build(
      BuildContext context, double shrinkOffset, bool overlapsContent) {
    var progress = shrinkOffset / (200 - 50);
    progress = progress > 0 ? progress : 0;
    progress = progress > 1 ? 1 : progress;
    final avatarAlignTween1 = AlignmentTween(
      begin: const Alignment(0, 0.65),
      end: const Alignment(0, 0.25),
    );

    return Material(
      color: Colors.transparent,
      child: Stack(
        children: [
          const SizedBox(height: double.maxFinite),
          Positioned(
            left: 20,
            top: 50,
            child: GestureDetector(
              onTap: () => Navigator.pop(context),
              child: const Icon(
                Icons.close,
                color: Colors.white,
                size: 30,
              ),
            ),
          ),
          Align(
              alignment: avatarAlignTween1.lerp(progress),
              child: Container(height: 300, width: 300, color: Colors.white)),
        ],
      ),
    );
  }

  @override
  bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) {
    return true;
  }

  @override
  double get maxExtent => max;

  @override
  double get minExtent => min;
}

1

There are 1 answers

0
Md. Yeasin Sheikh On

Here is Stack approach having Appbar behind body while scrolling.

class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
          Align(
            alignment: Alignment.topCenter,
            child: Container(
              height: 200,
              width: 200,
              color: Colors.deepPurple,
            ),
          ),
          Positioned(
            child: Padding(
              padding: const EdgeInsets.only(top: 100), //always padding
              child: CustomScrollView(
                slivers: [
                  SliverPadding(
                    padding: const EdgeInsets.only(top: 200),
                    sliver: SliverToBoxAdapter(
                      child: Container(
                        height: 1000,
                        width: double.infinity,
                        color: Colors.red,
                      ),
                    ),
                  )
                ],
              ),
            ),
          ),
        ],
      ),
    );
  }