how to use multi scroll in one screen -Flutter

Issue

I want to create an web ui in flutter like trello in that I want one horizontal primary scroll and one vertical secondary scroll but I am not able to scroll vertically in column I attach what I want to create and my code and if you still not understand please let me know

enter image description here

Here is my code :-


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

  // Use this for set width of card and row in list
  final double cardWidth = 180.0;
  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        Expanded(child: _getSideMenu()),
        Container(
          height: Get.height,
          width: 1,
          color: scrollBarColor,
        ),
        Expanded(
          child: _getMainScreen(),
          flex: 6,
        ),
      ],
    );
  }

  Widget _getMainScreen() {
    return SingleChildScrollView(
      scrollDirection: Axis.horizontal,
      child: ListView.builder(
          itemCount: 4,
          shrinkWrap: true,
          physics: NeverScrollableScrollPhysics(),
          scrollDirection: Axis.horizontal,
          padding: EdgeInsets.zero,
          itemBuilder: (context, i) {
            return Row(
              children: [
                Column(
                  mainAxisAlignment: MainAxisAlignment.start,
                  children: [
                    SizedBox(
                      width: cardWidth,
                      child: Row(
                        children: [
                          (10.0).addWSpace(),
                          "29".h3(
                              size: 25,
                              weight: FontWeight.w700,
                              color: GrayColor),
                          (5.0).addWSpace(),
                          Expanded(
                              child: "Sun".h3(
                                  color: GrayColor,
                                  weight: FontWeight.w400,
                                  size: 15)),
                          (10.0).addWSpace(),
                        ],
                      ),
                    ),
                    Container(
                      color: scrollBarColor,
                      height: 1,
                      width: cardWidth,
                    ),
                    SizedBox(
                      width: cardWidth,
                      child: Row(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          SingleChildScrollView(
                            primary: false,
                            child: Column(
                              mainAxisAlignment: MainAxisAlignment.start,
                              children: [
                                PlaningWeekCard(
                                  device: Device.Web,
                                  onTap: () {},
                                  width: cardWidth,
                                ),
                                PlaningWeekCard(
                                  device: Device.Web,
                                  onTap: () {},
                                  width: cardWidth,
                                ),
                                PlaningWeekCard(
                                  device: Device.Web,
                                  onTap: () {},
                                  width: cardWidth,
                                ),
                                PlaningWeekCard(
                                  device: Device.Web,
                                  onTap: () {},
                                  width: cardWidth,
                                ),
                                PlaningWeekCard(
                                  device: Device.Web,
                                  onTap: () {},
                                  width: cardWidth,
                                ),
                                PlaningWeekCard(
                                  device: Device.Web,
                                  onTap: () {},
                                  width: cardWidth,
                                ),
                              ],
                            ),
                          ),
                          Container(
                            height: Get.height,
                            width: 1,
                            color: scrollBarColor,
                          ),
                        ],
                      ),
                    ),
                  ],
                ),
              ],
            );
          }),
    );
  }

  Widget _getSideMenu() {
    return Container(
      height: Get.height,
      // width: 220,
      child: SingleChildScrollView(
        padding: EdgeInsets.zero,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            "Employers".h3(weight: FontWeight.w700, size: 22),
            (10.0).addHSpace(),
            PerytonSearchField(
              hintText: 'Name',
            ),
            (10.0).addHSpace(),
            ExpansionTile(
              title: Row(
                children: [
                  PerytonCheckBox(val: false),
                  (5.0).addWSpace(),
                  Expanded(child: "Codonnier Offieces".expansionTileTittleWeb())
                ],
              ),
              children: [
                _getRow("Norway office"),
                _getRow("Surat office"),
                _getRow("Bardoli office"),
                _getRow("Usa office"),
              ],
            ),
            (10.0).addHSpace(),
            ExpansionTile(
              title: Row(
                children: [
                  PerytonCheckBox(val: false),
                  (5.0).addWSpace(),
                  Expanded(child: "Codonnier Branches".expansionTileTittleWeb())
                ],
              ),
              children: [
                _getRow("Amsterdam office"),
                _getRow("Surat office"),
                _getRow("Suart-6 office"),
                _getRow("california office"),
              ],
            ),
            (10.0).addHSpace(),
            ExpansionTile(
              title: Row(
                children: [
                  PerytonCheckBox(val: false),
                  (5.0).addWSpace(),
                  Expanded(
                      child: "Codonnier sub branches".expansionTileTittleWeb())
                ],
              ),
              children: [
                _getRow("van gogh branch"),
                _getRow("Mota varacha branch"),
                _getRow("vesu branch"),
                _getRow("san francisco office"),
              ],
            ),
            (10.0).addHSpace(),
            "Workers".h3(weight: FontWeight.w700, size: 22),
            (10.0).addHSpace(),
            PerytonSearchField(
              hintText: 'Name',
            ),
            (10.0).addHSpace(),
            _getRow("Harsh codonnier"),
            (10.0).addHSpace(),
            _getRow("Dipak codonnier"),
            (10.0).addHSpace(),
            _getRow("Subham codonnier"),
            (10.0).addHSpace(),
            _getRow("ravi codonnier"),
            (10.0).addHSpace(),
          ],
        ).pSymmetricOnly(horizontal: 10),
      ),
    );
  }

  Widget _getRow(String name) {
    return Row(
      children: [
        PerytonCheckBox(val: false),
        (5.0).addWSpace(),
        Expanded(child: name.expansionTileWeb())
      ],
    );
  }
}


Here is my card widget:-

class PlaningDayCard extends StatelessWidget {
  PlaningDayCard(
      {Key? key,
      required this.device,
      required this.onTap,
      required this.width})
      : super(key: key);
  final Device device;
  final double width;
  final Function onTap;
  @override
  Widget build(BuildContext context) {
    return ResponsiveWidget(
        mobile: _getMobileCard(),
        tablet: _getWebCard(),
        desktop: _getWebCard(),
        device: device);
  }

  Widget _getWebCard() {
    return SizedBox(
      width: width - 2,
      child: Card(
          color: Colors.white,
          shape: RoundedRectangleBorder(
            side: BorderSide(color: Colors.white, width: 0.0),
            borderRadius: BorderRadius.circular(15),
          ),
          child: Material(
            borderRadius: BorderRadius.circular(15),
            clipBehavior: Clip.antiAlias,
            color: Colors.transparent,
            child: InkWell(
              onTap: () {
                onTap.call();
              },
              child: Column(
                mainAxisAlignment: MainAxisAlignment.start,
                children: [
                  Row(
                    children: [
                      Expanded(
                        child: "Scrubbing sinks, tubs, showers"
                            .h2(weight: FontWeight.w700, size: 15),
                      ),
                    ],
                  ),
                  (6.0).addHSpace(),
                  Row(
                    children: [
                      ImageAssetIconWithColor(
                        color: GrayColor,
                        size: 15,
                        image: ImageIcons.icTriangle,
                      ),
                      (8.0).addWSpace(),
                      Expanded(
                        child: "Main Office".h2(
                            weight: FontWeight.w500,
                            color: GrayColor,
                            size: 14),
                      ),
                    ],
                  ),
                  (8.0).addWSpace(),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.end,
                    children: [
                      "09:00—13:00".h2(
                          weight: FontWeight.w700, color: GrayColor, size: 13),
                    ],
                  )
                ],
              ).pSymmetricOnly(vertical: 5, horizontal: 6),
            ),
          )),
    );
  }

  Widget _getMobileCard() {
    return SizedBox(
      width: width - 2,
      child: Card(
          color: Colors.white,
          shape: RoundedRectangleBorder(
            side: BorderSide(color: Colors.white, width: 0.0),
            borderRadius: BorderRadius.circular(15.sp),
          ),
          child: Material(
            borderRadius: BorderRadius.circular(15.sp),
            clipBehavior: Clip.antiAlias,
            color: Colors.transparent,
            child: InkWell(
              onTap: () {
                onTap.call();
              },
              child: Column(
                children: [],
              ),
            ),
          )),
    );
  }
}

Solution

enter image description here

Complete Tested Code

import 'dart:math';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';

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

  @override
  State<TrelloExample> createState() => _TrelloExampleState();
}

class _TrelloExampleState extends State<TrelloExample> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: Padding(
        padding: const EdgeInsets.only(top: 64.0),
        child: ScrollConfiguration(
           behavior: ScrollConfiguration.of(context).copyWith(
            dragDevices: {
              PointerDeviceKind.touch,
              PointerDeviceKind.mouse,
            },
          ),
          child: SingleChildScrollView(
            physics: const ClampingScrollPhysics(),
            scrollDirection: Axis.horizontal,
            child: Row(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: List.generate(
                16,
                (index) => SingleChildScrollView(
                  physics: const ClampingScrollPhysics(),
                  child: Padding(
                    padding: EdgeInsets.only(
                        right: 16.0, left: index == 0 ? 16.0 : 0.0),
                    child: Column(
                      children: List.generate(
                        index % 2 == 1
                            ? 16
                            : index % 3 == 1
                                ? 8
                                : index % 1 == 1
                                    ? 4
                                    : 6,
                        (index) => Padding(
                          padding: const EdgeInsets.only(bottom: 16.0),
                          child: Material(
                            elevation: 4.0,
                            child: Container(
                              padding: const EdgeInsets.all(38.0),
                              color: Color(
                                      (Random().nextDouble() * 0xFFFFFF).toInt())
                                  .withOpacity(1.0),
                              child: Text(
                                "Trello Ticket Item $index",
                                style: const TextStyle(
                                  fontSize: 16.0,
                                  color: Colors.black,
                                  fontWeight: FontWeight.bold,
                                ),
                              ),
                            ),
                          ),
                        ),
                      ),
                    ),
                  ),
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

Answered By – MohammedAli

Answer Checked By – Candace Johnson (FlutterFixes Volunteer)

Leave a Reply

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