Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

flutter how to display a list by scrolling

i want the popular menu to scroll down as i scroll on the whole page , not as it is right now scrolling only on that little part

its a Listview.builder inside a Listview

Demo : https://i.stack.imgur.com/TZ8xH.gif

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

here is the full code

its commented where the Listview and Listview.builder are

ctrl+f search this "//////" to quickly find them

import 'dart:async';
import 'package:custom_refresh_indicator/custom_refresh_indicator.dart';

import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:foodninja/consts.dart';
import 'package:lottie/lottie.dart';
 
Color whiteBcg = const Color.fromARGB(255, 255, 255, 255);
Color limeColor = const Color.fromARGB(204, 77, 200, 118);
Color blackColor = Colors.black;
Color orangeInside = const Color.fromARGB(255, 210, 122, 0);
Color orangeOutside = const Color.fromARGB(45, 210, 123, 0);
Color cardBcg = const Color.fromRGBO(238, 238, 238, 1);
Color subText = const Color.fromARGB(255, 164, 164, 164);

class MyIconButton extends StatelessWidget {
  const MyIconButton({
    Key? key,
    required this.icon,
    required this.onClickAction,
  }) : super(key: key);

  final IconData icon;
  final Function onClickAction;

  @override
  Widget build(BuildContext context) {
    return Container(
        height: 50,
        width: 50,
        decoration: BoxDecoration(
            color: orangeOutside,
            // border: Border.all(
            //   color: Colors.red,
            // ),
            borderRadius: BorderRadius.circular(15)),
        child: TextButton(
          style: ButtonStyle(
            backgroundColor: MaterialStateProperty.all<Color>(
                const Color.fromARGB(2, 255, 149, 0)),
          ),
          onPressed: () => onClickAction(),
          child: Icon(
            icon,
            color: orangeInside,
          ),
        ));
  }
}

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

  @override
  Widget build(BuildContext context) {
    double h = MediaQuery.of(context).size.height;
    double w = MediaQuery.of(context).size.width;
    return Scaffold(
      body: CustomRefreshIndicator(
        onRefresh: () {
          return Future(
            () {},
          );
        },
        builder: (
          BuildContext context,
          Widget child,
          IndicatorController controller,
        ) {
          return AnimatedBuilder(
            animation: controller,
            builder: (BuildContext context, _) {
              return Stack(
                children: <Widget>[
                  if (controller.isDragging ||
                      controller.isArmed ||
                      controller.isLoading)
                    Positioned(
                      left: w * 0.37,
                      top: controller.value * 50,
                      child: SizedBox(
                        height: 100,
                        width: 100,
                        child: Transform.translate(
                            offset: Offset(0, controller.value * 20),
                            child: Transform.scale(
                                scale: controller.value *1.5,
                                child:
                                    Lottie.asset("assets/burgerBounce.json"))),
                      ),
                    ),
                  // if (controller.isArmed)
                  //   Positioned(
                  //     left: 0,
                  //     top: 25 * controller.value,
                  //     child: SizedBox(
                  //       height: 100,
                  //       width: 100,
                  //       child: Lottie.asset("assets/icecream.json"),
                  //     ),
                  //   ),
                  Transform.translate(
                    offset: const Offset(0, 0),
                    child: child,
                  )
                ],
              );
            },
          );
        },
        child: ListView(physics: const BouncingScrollPhysics(), children: [ ///////the list view
          SafeArea(
            child: Stack(children: [
              SizedBox(
                width: 500,
                child: Image.asset(
                  'assets/PhoneVerificationPattern.png',
                  fit: BoxFit.fill,
                ),
              ),
              Padding(
                padding: const EdgeInsets.all(20.0),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    const SizedBox(
                      height: 30,
                    ),
                    Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: [
                          const Text(
                            "Find your \nfavorite food",
                            style: TextStyle(
                                fontSize: 35, fontWeight: FontWeight.bold),
                          ),
                          MyIconButton(
                            icon: Icons.notifications_none,
                            onClickAction: () {},
                          ),
                        ]),
                    const SizedBox(
                      height: 20,
                    ),
                    Container(
                      alignment: Alignment.center,
                      height: 70,
                      width: w,
                      decoration: BoxDecoration(
                          color: orangeOutside,
                          // border: Border.all(
                          //   color: Colors.red,
                          // ),
                          borderRadius: BorderRadius.circular(15)),
                      child: TextFormField(
                          style: TextStyle(color: orangeInside),
                          decoration: InputDecoration(
                              hintText: "what do you want to order ?",
                              hintStyle: TextStyle(color: orangeInside),
                              prefixIconColor: orangeInside,
                              fillColor: orangeInside,
                              focusColor: orangeInside,
                              border: InputBorder.none,
                              focusedBorder: InputBorder.none,
                              prefixIcon: Icon(
                                Icons.search,
                                color: orangeInside,
                              ),
                              contentPadding:
                                  EdgeInsets.fromLTRB(0, 14, 0, 0))),
                    ),
                    const SizedBox(
                      height: 20,
                    ),
                    PromoAdvert(h: h, w: w),
                    const SizedBox(
                      height: 15,
                    ),
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: [
                        const Text(
                          "Nearest resturants",
                          style: TextStyle(
                              fontSize: 18, fontWeight: FontWeight.bold),
                        ),
                        RichText(
                          text: TextSpan(
                            children: [
                              TextSpan(
                                  text: "View more",
                                  style: TextStyle(
                                    fontSize: 15,
                                    color: orangeInside,
                                  ),
                                  recognizer: TapGestureRecognizer()
                                    ..onTap = () {}),
                            ],
                          ),
                        ),
                      ],
                    ),
                    const SizedBox(
                      height: 15,
                    ),
                    NearestResturants(w: w, h: h),
                    const SizedBox(
                      height: 15,
                    ),
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: [
                        const Text(
                          "Popular menu",
                          style: TextStyle(
                              fontSize: 18, fontWeight: FontWeight.bold),
                        ),
                        RichText(
                          text: TextSpan(
                            children: [
                              TextSpan(
                                  text: "View more",
                                  style: TextStyle(
                                    fontSize: 15,
                                    color: orangeInside,
                                  ),
                                  recognizer: TapGestureRecognizer()
                                    ..onTap = () {}),
                            ],
                          ),
                        ),
                      ],
                    ),
                    const SizedBox(
                      height: 20,
                    ),
                    SizedBox(
                      height: 70,
                      width: 400,
                      child: ListView.builder( ////////////////List view builder where the problem is
                        shrinkWrap: true,
                        scrollDirection: Axis.vertical,
                        itemCount: 4,
                        itemBuilder: (context, index) => Container(
                            height: 70,
                            width: 400,
                            decoration: BoxDecoration(
                                color: cardBcg,
                                // border: Border.all(
                                //   color: Colors.red,
                                // ),
                                borderRadius: BorderRadius.circular(15)),
                            child: Row(
                              children: [
                                Padding(
                                  padding:
                                      const EdgeInsets.fromLTRB(9, 5, 0, 5),
                                  child: Container(
                                    width: 50,
                                    decoration: BoxDecoration(
                                      image: DecorationImage(
                                        image: AssetImage(
                                          nearestResturantsContentList[index]
                                              .image,
                                        ),
                                      ),
                                      borderRadius: BorderRadius.circular(15),
                                    ),
                                  ),
                                ),
                                const SizedBox(
                                  width: 20,
                                ),
                                Column(
                                  crossAxisAlignment: CrossAxisAlignment.start,
                                  mainAxisAlignment: MainAxisAlignment.center,
                                  children: [
                                    Text(
                                      "Fruit Salade ",
                                      textAlign: TextAlign.start,
                                    ),
                                    Text(
                                      "Vegan resto",
                                      textAlign: TextAlign.start,
                                      style: TextStyle(color: subText),
                                    ),
                                  ],
                                ),
                                const SizedBox(
                                  width: 150,
                                ),
                                Text(
                                  "7\$",
                                  textAlign: TextAlign.start,
                                  style: TextStyle(
                                      color: const Color.fromARGB(
                                          255, 254, 171, 29),
                                      fontSize: 23),
                                )
                              ],
                            )),
                      ),
                    ),
                  ],
                ),
              )
            ]),
          ),
        ]),
      ),
    );
  }
}

class NearestResturantsContent {
  late String image;
  late String text;
  late String subText;

  NearestResturantsContent(
    this.image,
    this.text,
    this.subText,
  );
}

List<NearestResturantsContent> nearestResturantsContentList = [
  NearestResturantsContent(
    "assets/veganRestoLogo.png",
    "veganResto",
    "3KM",
  ),
  NearestResturantsContent(
    "assets/AjintiLogo.png",
    "Ajinti",
    "6KM",
  ),
  NearestResturantsContent(
    "assets/ChefGoLogo.png",
    "ChefGo",
    "10KM",
  ),
  NearestResturantsContent(
    "assets/BakeryLogo.png",
    "Bakery",
    "3KM",
  ),
  NearestResturantsContent(
    "assets/healthyFoodLogo.png",
    "healthyFood",
    "5KM",
  ),
  NearestResturantsContent(
    "assets/windowstoLogo.png",
    "windowsto",
    "3KM",
  ),
];

class NearestResturants extends StatelessWidget {
  const NearestResturants({
    Key? key,
    required this.w,
    required this.h,
  }) : super(key: key);

  final double w;
  final double h;

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: w,
      height: h * 0.22,
      child: ListView.builder(
        scrollDirection: Axis.horizontal,
        itemCount: nearestResturantsContentList.length,
        itemBuilder: (context, index) {
          return Container(
            margin: const EdgeInsets.fromLTRB(0, 0, 10, 0),
            width: w * 0.4,
            height: h * 0.22,
            decoration: BoxDecoration(
                color: cardBcg,
                // border: Border.all(
                //   color: Colors.red,
                // ),
                borderRadius: BorderRadius.circular(15)),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                SizedBox(
                  child: SizedBox(
                    height: 90,
                    width: 90,
                    child: Image.asset(
                      nearestResturantsContentList[index].image,
                      fit: BoxFit.fill,
                    ),
                  ),
                ),
                Text(
                  nearestResturantsContentList[index].text,
                  style: const TextStyle(
                      fontSize: 20,
                      fontWeight: FontWeight.bold,
                      overflow: TextOverflow.ellipsis),
                ),
                const SizedBox(
                  height: 5,
                ),
                Text(
                  nearestResturantsContentList[index].subText,
                  style: TextStyle(
                      color: subText,
                      fontSize: 13,
                      fontWeight: FontWeight.bold,
                      overflow: TextOverflow.ellipsis),
                ),
              ],
            ),
          );
        },
      ),
    );
  }
}

class PromoAdvertContent {
  late String image;
  late String text;
  late String subText;
  late Color color;
  PromoAdvertContent(this.image, this.text, this.subText, this.color);
}

List<PromoAdvertContent> promoAdvertContentList = [
  PromoAdvertContent("assets/promoAdvert.png", "Special deal for \nOctober",
      "Buy now", limeColor),
  PromoAdvertContent("assets/promoAdvert.png", "Special deal for \nOctober",
      "check out", orangeInside),
  PromoAdvertContent(
      "assets/promoAdvert.png", "No way this \nOctober", "check out", subText)
];

class PromoAdvert extends StatelessWidget {
  const PromoAdvert({
    Key? key,
    required this.h,
    required this.w,
  }) : super(key: key);

  final double h;
  final double w;

  @override
  Widget build(BuildContext context) {
    bool isScrollingToRight = true;
    int currentPage = 0;
    PageController scrollController = PageController(initialPage: 0);

 
    void _scrollToBottom() {
      if (currentPage < promoAdvertContentList.length && isScrollingToRight) {
        currentPage++;
      } else if (!isScrollingToRight && currentPage == 0) {
        currentPage++;
        isScrollingToRight = true;
      } else {
        isScrollingToRight = false;
        currentPage--;
      }
      if (scrollController.hasClients) {
        scrollController.animateToPage(
          currentPage,
          duration: const Duration(milliseconds: 1000),
          curve: Curves.easeOut,
        );
      }
    }

    WidgetsBinding.instance.addPostFrameCallback(
        (_) => Timer.periodic(const Duration(seconds: 15), (_) {
              _scrollToBottom();
            }));

    return SizedBox(
      width: w,
      height: h * 0.217,
      child: CustomRefreshIndicator(
        onRefresh: () {
          return Future(
            () {},
          );
        },
        builder: (
          BuildContext context,
          Widget child,
          IndicatorController controller,
        ) {
          return AnimatedBuilder(
            animation: controller,
            builder: (BuildContext context, _) {
              return Stack(
                children: <Widget>[
                  if (controller.isDragging ||
                      controller.isArmed ||
                      controller.isLoading)
                    Positioned(
                      left: 0,
                      top: h * 0.05,
                      child: SizedBox(
                        height: 100,
                        width: 100,
                        child: Transform.translate(
                            offset: Offset(-controller.value * 20, 0),
                            child: Transform.rotate(
                                angle: 11,
                                child: Lottie.asset("assets/icecream.json"))),
                      ),
                    ),
                  // if (controller.isArmed)
                  //   Positioned(
                  //     left: 0,
                  //     top: 25 * controller.value,
                  //     child: SizedBox(
                  //       height: 100,
                  //       width: 100,
                  //       child: Lottie.asset("assets/icecream.json"),
                  //     ),
                  //   ),
                  Transform.translate(
                    offset: const Offset(0, 0),
                    child: child,
                  )
                ],
              );
            },
          );
        },
        child: PageView.builder(
          controller: scrollController,
          physics: const BouncingScrollPhysics(),
          scrollDirection: Axis.horizontal,
          itemCount: promoAdvertContentList.length,
          itemBuilder: (context, index) {
            if (promoAdvertContentList.length == index) {
              print('a"sqdqsqs');
              CircularProgressIndicator();
            }
            return Container(
              width: h * 0.47,
              height: 160,
              decoration: BoxDecoration(
                  color: promoAdvertContentList[index].color,
                  // border: Border.all(
                  //   color: Colors.red,
                  // ),
                  borderRadius: BorderRadius.circular(15)),
              child: Stack(children: [
                SizedBox(
                  height: 160,
                  width: h * 0.47,
                  child: Image.asset(
                    promoAdvertContentList[index].image,
                    fit: BoxFit.fill,
                  ),
                ),
                Positioned(
                    top: 30,
                    right: 5,
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text(
                          promoAdvertContentList[index].text,
                          style: TextStyle(
                              color: whiteBcg,
                              fontSize: 20,
                              fontWeight: FontWeight.bold),
                        ),
                        const SizedBox(
                          height: 10,
                        ),
                        NextButton(
                          h: h,
                          w: w,
                          text: promoAdvertContentList[index].subText,
                        )
                      ],
                    ))
              ]),
            );
          },
        ),
      ),
    );
  }
}

class NextButton extends StatelessWidget {
  const NextButton({
    Key? key,
    required this.h,
    required this.w,
    required this.text,
  }) : super(key: key);
  final double h;
  final double w;
  final String text;

  @override
  Widget build(BuildContext context) {
    return Center(
      child: SizedBox(
        height: 45,
        width: 100,
        child: Card(
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(5),
          ),
          elevation: 5,
          child: TextButton(
              style: ButtonStyle(
                  shape: MaterialStateProperty.all<RoundedRectangleBorder>(
                      RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(5),
                  )),
                  backgroundColor: MaterialStateProperty.all<Color>(whiteBcg)),
              onPressed: () {},
              child: Text(
                text,
                style: TextStyle(color: limeColor, fontSize: 15),
                overflow: TextOverflow.ellipsis,
                softWrap: false,
              )),
        ),
      ),
    );
  }
}

>Solution :

To the list view that is scrolling separately add physics

physics: NeverScrollableScrollPhysics(),

And remove sized box which is wrapping the listview

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading