Pin the layout below and start scrolling at certain position in flutter

Issue

I am trying to achieve the scroll behaviour as in gif in this link.
There is image slider which gets hidden when scroll and the title of the product goes to appbar title. Also there is a fixed button Add to Bag which is fixed but scrolls with the layout at certain screen position.

I could show and hide the Add to Bag buttton using vising visibility_detector. When scrolling slow its working but when scrolling fast the button is not visible.

I could achieve only this

enter image description here

I have tried as below:

Scaffold(
  body: SafeArea(
    child: CustomAppBar(
      centerTitle: false,
      expandedHeight: 355,
      searchIconShow: true,
      showBackButton: true,
      leadingWidget: const Icon(Icons.arrow_back),
      titleWidget: LayoutBuilder(
          builder: (BuildContext context, BoxConstraints constraints) {
      
        top = constraints.biggest.height;
        return top < 280
            ? FlexibleSpaceBar(
                centerTitle: false,
                titlePadding: const EdgeInsets.all(15),
                title: Container(
                  width: MediaQuery.of(context).size.width * 0.57,
                  height: 60,
                  padding: const EdgeInsets.fromLTRB(35, 0, 0, 0),
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      const Text("M.A.C Prep + Prep + Prime Fix+ -Original",
                          style: TextStyle(
                              overflow: TextOverflow.ellipsis,
                              color: Colors.black,
                              fontWeight: FontWeight.normal,
                              fontSize: 14)),
                      Expanded(
                        child: Row(
                          children: const [
                            Icon(Icons.star, size: 8, color: Colors.grey),
                            SizedBox(width: 2),
                            Text(
                              "4.1",
                              style: TextStyle(
                                  color: Colors.grey, fontSize: 10),
                            ),
                            SizedBox(width: 5),
                            Icon(Icons.circle, size: 5, color: Colors.grey),
                            SizedBox(width: 5),
                            Text("Rs 1200",
                                style: TextStyle(
                                    color: Colors.grey, fontSize: 10))
                          ],
                        ),
                      )
                    ],
                  ),
                ),
                background: Container())
            : FlexibleSpaceBar(
                centerTitle: false,
                titlePadding: const EdgeInsets.all(15),
                title: SingleChildScrollView(
                  physics:const NeverScrollableScrollPhysics(),
                  child: Container(
                    height:342,
                    padding: const EdgeInsets.fromLTRB(0, 135, 0, 0),
                    child: Column(
                      mainAxisSize: MainAxisSize.max,
                      children: [
                        _buildSlider(),
                        Row(
                          children: const [
                            Expanded(
                              child: Text(
                                  "M.A.C Prep + Prep + Prime Fix+ -Original",
                                  style: TextStyle(
                                      overflow: TextOverflow.ellipsis,
                                      color: Colors.black,
                                      fontWeight: FontWeight.normal,
                                      fontSize: 12)),
                            ),
                            Icon(
                              Icons.share,
                              color: Colors.black,
                              size: 20,
                            )
                          ],
                        ),
                        Row(
                          children: const [
                            Icon(Icons.star, size: 10, color: Colors.grey),
                            SizedBox(width: 2),
                            Text(
                              "4.1",
                              style:
                                  TextStyle(color: Colors.grey, fontSize: 10),
                            ),
                            SizedBox(width: 5),
                            Icon(Icons.circle, size: 5, color: Colors.grey),
                            SizedBox(width: 5),
                            Text("Rs 1200",
                                style: TextStyle(
                                    color: Colors.grey, fontSize: 10))
                          ],
                        )
                      ],
                    ),
                  ),
                ),
              );
      }),
      myWidget: Stack(children: [
        SingleChildScrollView(
          child: Column(
            children: [
              Container(height: 200, color: Colors.green),
              Container(height: 200, color: Colors.yellow),
              Container(height: 200, color: Colors.pink),
              Container(height: 200, color: Colors.grey),
              Container(height: 200, color: Colors.blueGrey),
              Container(height: 200, color: Colors.indigo),
              Container(height: 200, color: Colors.purple),
              Container(height: 200, color: Colors.green),
              Container(height: 200, color: Colors.yellow),
              Container(height: 200, color: Colors.pink),
              Container(height: 200, color: Colors.grey),
              VisibilityDetector(
                key: Key('my-widget-key'),
                onVisibilityChanged: (visibility) {
                  var visiblePercentage =
                      visibility.visibleFraction * 100;
                  if (visiblePercentage < 0) {
                    setState(() {
                      showBottomButton = false;
                    });
                  }

                  else{
                    setState(() {
                      showBottomButton = true;
                    });
                  }
                },
                child: Padding(
                  padding: const EdgeInsets.all(10.0),
                  child: Container(
                      padding: const EdgeInsets.all(20),
                      width: MediaQuery.of(context).size.width,
                      color: Colors.red,
                      child: const Text("Add to Bag",
                          style: TextStyle(color: Colors.white))),
                ),
              ),
              VisibilityDetector(
                  key: Key('my-widget-key2'),
                  onVisibilityChanged: (visibility) {

                    var visiblePercentage =
                        visibility.visibleFraction * 100;
                    if (visiblePercentage < 0) {
                      setState(() {
                        showBottomButton = true;
                      });
                    } else {
                      setState(() {
                        showBottomButton = false;
                      });
                    }
                  },
                  child: Column(
                    children: [
                      Container(height: 200, color: Colors.black),
                      Container(height: 200, color: Colors.indigo),
                      Container(height: 200, color: Colors.purple),
                      Container(height: 200, color: Colors.indigo),
                      Container(height: 200, color: Colors.purple),
                      Container(height: 200, color: Colors.indigo),
                      Container(height: 200, color: Colors.black),
                      Container(height: 200, color: Colors.purple),
                      Container(height: 200, color: Colors.black),
                      Container(height: 200, color: Colors.purple),
                      Container(height: 200, color: Colors.black),
                      Container(height: 200, color: Colors.purple),
                      Container(height: 200, color: Colors.black),
                      Container(height: 200, color: Colors.purple),
                      Container(height: 200, color: Colors.black),
                      Container(height: 200, color: Colors.purple),
                    ],
                  )),
            ],
          ),
        ),
        Visibility(
          visible: showBottomButton,
          child: Align(
            alignment: Alignment.bottomCenter,
            child: Padding(
              padding: const EdgeInsets.all(8.0),
              child: Container(
                  padding: const EdgeInsets.all(20),
                  width: MediaQuery.of(context).size.width,
                  color: Colors.red,
                  child: const Text("Add to Bag",
                      style: TextStyle(color: Colors.white))),
            ),
          ),
        ),
      ]),
    ),
  ),
);

And I could achieve only this

Solution

Solved it there was problem in logic. Just changed if (visiblePercentage < 0) to

if (visiblePercentage <= 0)

Answered By – Nbn

Answer Checked By – Clifford M. (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *