Sanchit Batra
Sanchit Batra

Reputation: 49

Make parent scroll with child in flutter

So, I have a widget in flutter that is inside a SingleChildScrollView. Inside the scrollview, I have a PageView. Now the issue is that the PageView contains different pages such as Home, About, etc. but they are not scrollable. If I wrap them in SingleChildScrollView individually, then they scroll but without the footer that is in the Parent class always show up in front of all of it.

Parent class:

import 'package:experiments/home.dart';
import 'package:flutter/material.dart';

class MainStuff extends StatefulWidget {
  const MainStuff({super.key});

  @override
  State<MainStuff> createState() => _MainStuffState();
}

class _MainStuffState extends State<MainStuff> with TickerProviderStateMixin {
  late TabController _tabController;

  @override
  void initState() {
    super.initState();
    _tabController = TabController(length: 5, vsync: this);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        surfaceTintColor: Colors.white,
        toolbarHeight: 120,
        backgroundColor: Colors.white,
        centerTitle: false,
        title: Text("testing scrolling")
        scrolledUnderElevation: 20,
        elevation: 20,
      ),
      body: SingleChildScrollView(
        child: Column(
          children: [
            Material(
              elevation: 10,
              shadowColor: Colors.black26,
                color: Colors.white,
                child: TabBar(
                  labelColor: Colors.green[700],
                          labelStyle: TextStyle(fontWeight: FontWeight.w800),
                          tabs: [
                Tab(text: "Home", icon: Icon(Icons.home),),
                Tab(text: "Our Story", icon: Icon(Icons.people_alt),),
                Tab(text: "Shop", icon: Icon(Icons.storefront_outlined),),
                Tab(text: "Special Offers", icon: Icon(Icons.star),),
                Tab(text: "Contact Us", icon: Icon(Icons.call),)
                          ],
                          controller: _tabController,
                        ),
              ),
            Container(
              height: 500,
              child: TabBarView(
                controller: _tabController,
                children: [
                  Home(),
                  Center(child: Text("Our Story")),
                  Center(child: Text("Shop")),
                  Center(child: Text("Special Offers")),
                  Center(child: Text("Contact Us")),
                ],
              ),
            ),
Divider(),
           Padding(
                padding: const EdgeInsets.symmetric(
                    vertical: 16.0, horizontal: 128.0),
                child: Row(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                  SizedBox(
                    width: (MediaQuery.of(context).size.width - 346) * (1 / 3),
                    child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Container(
                              width: 200,
                              child: Image.asset("assets/images/logo.png")),
                          Text(
                              "text"),
                          TextButton.icon(
                              onPressed: () {
                                js.context
                                    .callMethod('open', ['mailto: [email protected]']);
                              },
                              label: Text(
                                "mail",
                                style: TextStyle(fontWeight: FontWeight.w900),
                              ),
                              icon: Icon(
                                Icons.email,
                                color: Color.fromRGBO(184, 31, 47, 1),
                              ),
                              style: TextButton.styleFrom(
                                  foregroundColor: Colors.black)),
                          TextButton.icon(
                              onPressed: () {
                                js.context.callMethod(
                                    'open', ['tel: number']);
                              },
                              label: Text(
                                "Number",
                                style: TextStyle(fontWeight: FontWeight.w900),
                              ),
                              icon: Icon(
                                Icons.phone,
                                color: Color.fromRGBO(184, 31, 47, 1),
                              ),
                              style: TextButton.styleFrom(
                                  foregroundColor: Colors.black)),
                          Text(
                              'Address',
                              style: TextStyle(fontWeight: FontWeight.w900)),
                          SizedBox(
                            height: 30,
                          ),
                          Row(
                            children: [
                              Icon(Icons.facebook),
                              SizedBox(
                                width: 30,
                              ),
                              Icon(Icons.facebook),
                              SizedBox(
                                width: 30,
                              ),
                              Icon(Icons.facebook)
                            ],
                          ),
                          SizedBox(
                            height: 30,
                          ),
                          Text(
                            "Copyright line",
                            style: TextStyle(color: Colors.grey),
                          )
                        ]),
                  ),
                  SizedBox(width: 30,),
                    Row(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        SizedBox(
                    width: (MediaQuery.of(context).size.width - 346) * (1 / 6),
                        child: Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                          Text("Our Story"),
                          SizedBox(height: 20,),
                          Text("Contact Us"),
                          SizedBox(height: 20,),
                          Text("My Account"),
                          SizedBox(height: 20,),
                          Text("Track My Order"),
                          SizedBox(height: 20,),
                          Text("Our Blog"),
                          SizedBox(height: 20,),
                    ],),),
                    SizedBox(width: 30,),
                      SizedBox(
                    width: (MediaQuery.of(context).size.width - 346) * (1 / 6),
                      child: Column(
                        mainAxisAlignment: MainAxisAlignment.start,
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                        Text("Terms of Service"),
                        SizedBox(height: 20,),
                        Text("Shipping, Returns & Refund Policy"),
                        SizedBox(height: 20,),
                        Text("Privacy Policy"),
                        SizedBox(height: 20,),
                          ],),
                    ),
                      ],
                    ),
                  SizedBox(width: 30,),
                  SizedBox(
                    width: (MediaQuery.of(context).size.width - 346) * (1 / 3),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                      Text("NEWSLETTER", style: TextStyle(fontWeight: FontWeight.bold)),
                      SizedBox(height: 20,),
                      Text("Don't miss out thousands of great deals and promotions."),
                      SizedBox(height: 20,),
                      TextField(decoration: InputDecoration(border: OutlineInputBorder(borderSide: BorderSide(color: Colors.black)), hintText: "Email Address"),),
                      SizedBox(height: 20,),
                      ElevatedButton(onPressed: () {}, child: Padding(
                        padding: const EdgeInsets.symmetric(horizontal: 1.0, vertical: 8.0),
                        child: Text("Subscribe"),
                      ), style: ElevatedButton.styleFrom(foregroundColor: Colors.white, backgroundColor: Colors.green[900], shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10))),),
                    ],),

                  )
                ]),
              )
          ],
        ),
      ),
    );
  }
}

Child class:

import 'package:flutter/material.dart';

class Home extends StatefulWidget {
  const Home({super.key});

  @override
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {
  List<String> images = ["1.png", "2.png"];
  PageController _sliderController = PageController();
  int currImage = 0;
  late PageView image_carousel;
  @override
  void initState() {
    super.initState();
    image_carousel = PageView.builder(
              controller: _sliderController,
              scrollDirection: Axis.horizontal,
              itemBuilder: (context, index) => Image.asset(
                "images/slider_images/${images[index % images.length]}",
                // fit: BoxFit.cover,
              ),
            );
  }
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        ConstrainedBox(
          constraints: const BoxConstraints(maxHeight: 400),
          child: Stack(children: [
            image_carousel,
            Align(
              alignment: Alignment.centerLeft,
              child: ElevatedButton(
                  onPressed: () {
                    _sliderController.previousPage(
                        duration: Duration(seconds: 1), curve: Curves.easeIn);
                  },
                  style: ElevatedButton.styleFrom(
                      elevation: 0,
                      shape: CircleBorder(),
                      backgroundColor: Colors.white70,
                      foregroundColor: Colors.black),
                  child: const Padding(
                    padding: EdgeInsets.all(8.0),
                    child: Icon(
                      Icons.arrow_back_ios_rounded,
                      size: 40,
                    ),
                  )),
            ),
            Align(
              alignment: Alignment.centerRight,
              child: ElevatedButton(
                  onPressed: () {
                    _sliderController.nextPage(
                        duration: Duration(seconds: 1), curve: Curves.easeIn);
                  },
                  style: ElevatedButton.styleFrom(
                      elevation: 0,
                      shape: CircleBorder(),
                      backgroundColor: Colors.white70,
                      foregroundColor: Colors.black),
                  child: Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: Icon(
                      Icons.arrow_forward_ios_rounded,
                      size: 40,
                    ),
                  )),
            )
          ]),
        ),
        Row(
          children: [
            for (int i = 0; i < 4; i++)
              Container(
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(20),
                ),
                  padding: const EdgeInsets.all(8.0),
                  child: Image(image: AssetImage("assets/images/options_banner.png"))),
        ])
      ],
    );
  }
}

I want the child to scroll with the parent such that on scrolling, the footer part that is below the divider in the parent class appears after everything has scrolled. It should not come in front of all the content.

PS: I am using flutter on the web.

Upvotes: 1

Views: 38

Answers (0)

Related Questions