Home > Mobile >  Scrollable Column and ListView.builder
Scrollable Column and ListView.builder

Time:10-23

I want to have a Column and ListView.builder to be scrollable using the SingleChildScrollView. I tried wrapping both the Column or the SingleChildScrollView with Expanded but I'm still not winning. I just want the ListView.builder and the Container above it to be scrollable. Please help...

I am getting an error that says : RenderFlex children have non-zero flex but incoming height constraints are unbounded.

import 'package:flutter/material.dart';
import 'package:ionicons/ionicons.dart';
import 'package:provider/provider.dart';
import '../widgets/product_item.dart';
import '../providers/products.dart';

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

  @override
  Widget build(BuildContext context) {
    final productsData = Provider.of<Products>(context);
    final products = productsData.items;
    return Scaffold(
      appBar: AppBar(
        leading: IconButton(
          onPressed: () {},
          icon: const Icon(
            Ionicons.notifications_outline,
          ),
        ),
        title: SizedBox(
          width: MediaQuery.of(context).size.width * 0.3,
          height: MediaQuery.of(context).size.height * 0.1,
          child: Image.asset(
            'assets/logo.png',
            fit: BoxFit.contain,
          ),
        ),
        actions: [
          IconButton(
            onPressed: () {},
            icon: const Icon(
              Ionicons.cart_outline,
            ),
          ),
        ],
      ),
      body: SingleChildScrollView(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Container(
              height: 140,
              width: MediaQuery.of(context).size.width * 0.9,
              decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(26.0),
                color: Colors.grey[300],
              ),
            ),
            Row(
              children: const [
                Padding(
                  padding: EdgeInsets.only(
                    left: 15.0,
                    top: 20.0,
                  ),
                  child: Text(
                    'Place Order',
                    style: TextStyle(
                      fontWeight: FontWeight.bold,
                      fontSize: 18.0,
                    ),
                  ),
                ),
              ],
            ),
            Expanded(
              child: ListView.builder(
                scrollDirection: Axis.vertical,
                itemCount: products.length,
                itemBuilder: (ctx, i) => ProductItem(
                  products[i].id,
                  products[i].name,
                  products[i].size,
                  products[i].price,
                  products[i].image,
                ),
              ),
            )
          ],
        ),
      ),
    );
  }
}

CodePudding user response:

This is one approach among thousands of solutions, it consists of nesting one listview inside another. If you wish you can make the listview.builder horizontal.

import 'package:flutter/material.dart';
import 'package:ionicons/ionicons.dart';
import 'package:provider/provider.dart';
import '../widgets/product_item.dart';
import '../providers/products.dart';

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

  @override
  Widget build(BuildContext context) {
    final productsData = Provider.of<Products>(context);
    final products = productsData.items;
    return Scaffold(
      appBar: AppBar(
        leading: IconButton(
          onPressed: () {},
          icon: const Icon(
            Ionicons.notifications_outline,
          ),
        ),
        title: SizedBox(
          width: MediaQuery.of(context).size.width * 0.3,
          height: MediaQuery.of(context).size.height * 0.1,
          child: Image.asset(
            'assets/logo.png',
            fit: BoxFit.contain,
          ),
        ),
        actions: [
          IconButton(
            onPressed: () {},
            icon: const Icon(
              Ionicons.cart_outline,
            ),
          ),
        ],
      ),
      body: ListView(
          scrollDirection: Axis.vertical,
          children: [
            Container(
              height: 140,
              width: MediaQuery.of(context).size.width * 0.9,
              decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(26.0),
                color: Colors.grey[300],
              ),
            ),
            Row(
              children: const [
                Padding(
                  padding: EdgeInsets.only(
                    left: 15.0,
                    top: 20.0,
                  ),
                  child: Text(
                    'Place Order',
                    style: TextStyle(
                      fontWeight: FontWeight.bold,
                      fontSize: 18.0,
                    ),
                  ),
                ),
              ],
            ),
            ListView.builder(
                scrollDirection: Axis.vertical,
                physics: const NeverScrollableScrollPhysics(),
                shrinkWrap: true,
                primary: false,
                itemCount: products.length,
                itemBuilder: (ctx, i) => ProductItem(
                  products[i].id,
                  products[i].name,
                  products[i].size,
                  products[i].price,
                  products[i].image,
                ),
            )
          ],
        ),
    );
  }
}

CodePudding user response:

// The solution to your problem is to make the Listview non using enter code here scrollable and set shrinkwrap to true. Then wrap the first column in SingleChildScrollView. You don't need Expanded or Flexible Widget for this approach.

import 'package:flutter/material.dart';

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

  @override
  Widget build(BuildContext context) {
    final productsData = Provider.of<Products>(context);
    final products = productsData.items;
    return Scaffold(
      appBar: AppBar(
        leading: IconButton(
          onPressed: () {},
          icon: const Icon(
            Icons.info_outline,
          ),
        ),
        title: SizedBox(
          width: MediaQuery.of(context).size.width * 0.3,
          height: MediaQuery.of(context).size.height * 0.1,
          child: Image.asset(
            'assets/logo.png',
            fit: BoxFit.contain,
          ),
        ),
        actions: [
          IconButton(
            onPressed: () {},
            icon: const Icon(
              Icons.shopping_cart_outlined,
            ),
          ),
        ],
      ),
      body: SingleChildScrollView(
        child: Column(
          // mainAxisSize: MainAxisSize.min,
          children: [
            Container(
              height: 140,
              width: MediaQuery.of(context).size.width * 0.9,
              decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(26.0),
                color: Colors.grey[300],
              ),
            ),
            Row(
              children: const [
                Padding(
                  padding: EdgeInsets.only(
                    left: 15.0,
                    top: 20.0,
                  ),
                  child: Text(
                    'Place Order',
                    style: TextStyle(
                      fontWeight: FontWeight.bold,
                      fontSize: 18.0,
                    ),
                  ),
                ),
              ],
            ),
            ListView.builder(
              shrinkWrap: true,
              itemCount: 10,
              physics: const NeverScrollableScrollPhysics(),
              itemBuilder: (ctx, i) => ProductItem(
                products[i].id,
                products[i].name,
                products[i].size,
                products[i].price,
                products[i].image,
              ),
            )
          ],
        ),
      ),
    );
  }
}

CodePudding user response:

Looking at your code, you don't need the SingleChildScrollView widget. Just remove it. The listView is built with a scroll behaviour, you dont need to add it.

Please, let me know if you meant something else and I can help.

If you still have the Renderflex error, then wrap your Column widget inside a Flexible widget

Flexible(child: Column(children:[..
  • Related