chichi
chichi

Reputation: 3292

Flutter: how to use ListView with expanded inside the nested column

@override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text(
          "Scrolling Viewww :( ",
          style: TextStyle(fontSize: 25),
        ),
        Column(
          children: [
            Container(
              height: 100,
              width: 100,
              color: Colors.blue,
            ),
            SizedBox(
              height: 10,
            ),
            Container(
              height: 100,
              width: 100,
              color: Colors.blue,
            ),
            SizedBox(
              height: 10,
            ),
            Column(children: [
              ListView( <------------------ **Making this Expanded**
                shrinkWrap: true,
                scrollDirection: Axis.vertical,
                children: [
                  Container(
                    height: 100,
                    width: 100,
                    color: Colors.red,
                  ),
                  SizedBox(
                    height: 10,
                  ),
                  Container(
                    height: 100,
                    width: 100,
                    color: Colors.red,
                  ),
                  SizedBox(
                    height: 10,
                  ),
                  Container(
                    height: 100,
                    width: 100,
                    color: Colors.red,
                  ),
                  SizedBox(
                    height: 10,
                  ),
                  Container(
                    height: 100,
                    width: 100,
                    color: Colors.red,
                  ),
                  SizedBox(
                    height: 10,
                  ),
                ],
              ),
            ]),
            Container(
              height: 100,
              width: 100,
              color: Colors.blue,
            ),
            SizedBox(
              height: 10,
            ),
          ],
        )
      ],
    );

enter image description here

I have tried to implement Expanded to resolved this. However, since it is nested twice, it was quite tricky. Only way that I could have done is just to set the Container() widget with given height.

But, in my real Column() widget, I have an AnimatedContainer that changes with its height. So, I want to find a way that I can do this with Expanded or Flexible.

I'd tried million different combinations. Nothing seems to work. How can I make the ListView that is inside the nested Column expandable?

Upvotes: 0

Views: 316

Answers (2)

KuKu
KuKu

Reputation: 7492

Did you want to fix two item over ListView?

I implemented your request.

enter image description here

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage>
    with SingleTickerProviderStateMixin {
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: _buildBody(),
      floatingActionButton: FloatingActionButton(
        onPressed: () {},
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }

  Widget _buildBody() {
    return SafeArea(
      child: Container(
        child: NestedScrollView(
          headerSliverBuilder: (context, value) {
            return [
              SliverPersistentHeader(
                pinned: true,
                delegate: _SliverAppBarDelegate(
                  minHeight: 40,
                  maxHeight: 40,
                  child: Container(
                    color: Colors.white,
                    child: Text(
                      "Scrolling Viewww :( ",
                      style: TextStyle(fontSize: 25),
                    ),
                  ),
                ),
              ),
              SliverPersistentHeader(
                pinned: true,
                delegate: _SliverAppBarDelegate(
                  minHeight: 90,
                  maxHeight: 90,
                  child: Container(
                    height: 100,
                    width: 100,
                    color: Colors.blue,
                    child: Text('box1'),
                  ),
                ),
              ),
              SliverPersistentHeader(
                pinned: true,
                delegate: _SliverAppBarDelegate(
                  minHeight: 90,
                  maxHeight: 90,
                  child: Container(
                    height: 100,
                    width: 100,
                    color: Colors.blue,
                    child: Text('box2'),
                  ),
                ),
              ),
            ];
          },
          body: Builder(
            builder: (BuildContext context) {
              final innerScrollController = PrimaryScrollController.of(context);
              return SingleChildScrollView(
                controller: innerScrollController,
                child: Column(
                  children: [
                    ListView(
                      shrinkWrap: true,
                      scrollDirection: Axis.vertical,
                      children: [
                        Container(
                          height: 100,
                          width: 100,
                          color: Colors.red,
                        ),
                        SizedBox(
                          height: 10,
                        ),
                        Container(
                          height: 100,
                          width: 100,
                          color: Colors.red,
                        ),
                        SizedBox(
                          height: 10,
                        ),
                        Container(
                          height: 100,
                          width: 100,
                          color: Colors.red,
                        ),
                        SizedBox(
                          height: 10,
                        ),
                        Container(
                          height: 100,
                          width: 100,
                          color: Colors.red,
                        ),
                        SizedBox(
                          height: 10,
                        ),
                        Container(
                          height: 100,
                          width: 100,
                          color: Colors.red,
                        ),
                        SizedBox(
                          height: 10,
                        ),
                      ],
                    ),
                    Container(
                      height: 100,
                      width: 100,
                      color: Colors.blue,
                    ),
                    SizedBox(
                      height: 10,
                    ),
                  ],
                ),
              );
            },
          ),
        ),
      ),
    );
  }
}

class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
  _SliverAppBarDelegate({
    @required this.minHeight,
    @required this.maxHeight,
    @required this.child,
  });
  final double minHeight;
  final double maxHeight;
  final Widget child;

  @override
  double get minExtent => minHeight;

  @override
  double get maxExtent => math.max(maxHeight, minHeight);

  @override
  Widget build(
      BuildContext context, double shrinkOffset, bool overlapsContent) {
    return SizedBox.expand(child: child);
  }

  @override
  bool shouldRebuild(_SliverAppBarDelegate oldDelegate) {
    return maxHeight != oldDelegate.maxHeight ||
        minHeight != oldDelegate.minHeight ||
        child != oldDelegate.child;
  }
}

Upvotes: 1

Tobotis
Tobotis

Reputation: 96

To avoid the bottom overflow, try wrapping a SingleChildScrollView around the first Column. Additionally you can play around with the mainAxisSize property of the different Columns.

Upvotes: 1

Related Questions