flutterlistviewscrollsinglechildscrollview

Using SingleChildScrollView while using scrolllable listview.builder (flutter)


This is my whole code:

import 'package:flutter/material.dart';
import 'package:testproject/components/event_tile.dart';
import 'package:testproject/components/mybutton.dart';

class MenuPage extends StatelessWidget {
  const MenuPage({super.key});

  @override
  Widget build(BuildContext context) {
    List EventList = [
      EventTile(
        name: "Mitama Matsuri festivial",
        price: "€ 49",
        imagePath: "lib/images/japan7.png",
        rating: "5",
        details: () {},
      ),
      EventTile(
        name: "Noddle Harmony Tokyo",
        price: "€ 18",
        imagePath: "lib/images/japan3.png",
        rating: "4",
        details: () {},
      ),
      EventTile(
        name: "Moun Fuji Tour",
        price: "€ 42",
        imagePath: "lib/images/japan6.png",
        rating: "4,3",
        details: () {},
      ),
    ];

    return Scaffold(
      backgroundColor: Color.fromARGB(255, 215, 165, 187),
      appBar: AppBar(
        title: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              "J A P A N",
              style: TextStyle(color: Colors.white),
            ),
            SizedBox(width: 10),
            Image.asset(
              "lib/images/japanflag.png",
              height: 20,
            ),
          ],
        ),
        backgroundColor: Colors.transparent,
        elevation: 0,
        leading: Icon(
          Icons.menu_rounded,
          color: Colors.white,
        ),
        actions: [
          Padding(
            padding: const EdgeInsets.only(right: 15.0),
            child: Icon(
              Icons.shopping_cart,
              color: Colors.white,
            ),
          )
        ],
      ),
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Container(
            padding: EdgeInsets.all(25),
            margin: EdgeInsets.symmetric(horizontal: 25),
            decoration: BoxDecoration(
              color: const Color(0x80d70127),
              borderRadius: BorderRadius.circular(20),
            ),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Column(
                  children: [
                    Text(
                      "32% Nachlass",
                      style: TextStyle(
                        fontSize: 22,
                      ),
                    ),
                    SizedBox(height: 15),
                    MyButton(mytext: "Buchen", event: () {})
                  ],
                ),
                Image.asset(
                  "lib/images/japan1.png",
                  height: 135,
                )
              ],
            ),
          ),
          SizedBox(height: 15),
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 25.0),
            child: TextField(
              decoration: InputDecoration(
                hintText: "Suche Event [funktioniert nicht]",
                enabledBorder: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(15),
                  borderSide: BorderSide(
                    color: Colors.white,
                    width: 2,
                  ),
                ),
                border: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(15),
                  borderSide: BorderSide(
                    color: Colors.white,
                    width: 2,
                  ),
                ),
              ),
            ),
          ),
          SizedBox(height: 13),
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 25.0),
            child: Text(
              "Events",
              style: TextStyle(
                fontSize: 20,
                fontWeight: FontWeight.bold,
                color: Colors.white,
              ),
            ),
          ),
          SizedBox(height: 5),
          Expanded(
            child: ListView.builder(
              itemBuilder: (context, index) => EventList[index],
              itemCount: EventList.length,
              scrollDirection: Axis.horizontal,
            ),
          ),
          SizedBox(height: 25),
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 25.0),
            child: Text(
              "Derzeit beliebt",
              style: TextStyle(
                  fontSize: 20,
                  fontWeight: FontWeight.bold,
                  color: Colors.white),
            ),
          ),
          SizedBox(height: 10),
          Container(
            padding: EdgeInsets.all(8),
            margin: EdgeInsets.symmetric(horizontal: 25),
            decoration: BoxDecoration(
                color: Color.fromARGB(255, 94, 185, 160),
                borderRadius: BorderRadius.circular(20)),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: [
                Image.asset(
                  "lib/images/japan2.png",
                  height: 115,
                ),
                Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      "Kimono Kultur",
                      style: TextStyle(
                          fontSize: 20,
                          fontWeight: FontWeight.bold,
                          color: Colors.white),
                    ),
                    SizedBox(height: 10),
                    Text(
                      "€ 45",
                      style: TextStyle(
                          fontSize: 18,
                          fontWeight: FontWeight.bold,
                          color: Colors.white), // TextStyle
                    )
                  ],
                ),
              ],
            ),
          ),
          SizedBox(height: 10),
        ],
      ),
    );
  }
}

I have a listView.builder right here:

Expanded(
            child: ListView.builder(
              itemBuilder: (context, index) => EventList[index],
              itemCount: EventList.length,
              scrollDirection: Axis.horizontal,
            ),
          ),

And I have to make the whole page scrollable, because there is not enough space to fit everything, I already got a bottom overflow.

By adding a SingleChildScrollView class right at the beginning of the body:

 body: Column( //right here
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Container(
            padding: EdgeInsets.all(25),
            margin: EdgeInsets.symmetric(horizontal: 25),
            decoration: BoxDecoration(
              color: const Color(0x80d70127),
              borderRadius: BorderRadius.circular(20),
            ),
            child: Row(

I run into the problem that everything disapears. Making shrinkWrap: true does nothing, and physics: NeverScrollableScrollPhysics() is not what I need, because the listView.builder still must scroll. Also in best case I want to keep the Expanded because the height variates How can I manage to do this?


Solution

  • I used CustomScrollView and SliverList instead of ListView.builder, it's not perfect because it has a defined height but it works. With that the SingleChildScrollView works also.

    Container(
                  height: 300,
                  child: CustomScrollView(
                    slivers: [
                      SliverList(
                        delegate: SliverChildBuilderDelegate(
                          (BuildContext context, int index) {
                            return eventList[index];
                          },
                          childCount: eventList.length,
                        ),
                      ),
                    ],
                    scrollDirection: Axis.horizontal,
                  ),
                ),