1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

  2. Anuncie Aqui ! Entre em contato fdantas@4each.com.br

[Flutter] How to make Column scrollable when overflowed but use expanded otherwise

Discussão em 'Mobile' iniciado por Stack, Setembro 21, 2021.

  1. Stack

    Stack Membro Participativo

    I am trying to achieve an effect where there is expandable content on the top end of a sidebar, and other links on the bottom of the sidebar. When the content on the top expands to the point it needs to scroll, the bottom links should scroll in the same view.

    Here is an example of what I am trying to do, except that it does not scroll. If I wrap a scrollable view around the column, that won't work with the spacer or expanded that is needed to keep the bottom links on bottom:

    import 'package:flutter/material.dart';

    const Color darkBlue = Color.fromARGB(255, 18, 32, 47);

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

    class MyApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
    return MaterialApp(
    theme: ThemeData.dark().copyWith(
    scaffoldBackgroundColor: darkBlue,
    ),
    debugShowCheckedModeBanner: false,
    home: Scaffold(
    body: Center(
    child: MyWidget(),
    ),
    ),
    );
    }
    }

    class MyWidget extends StatefulWidget {
    @override
    State<MyWidget> createState() {
    return MyWidgetState();
    }
    }

    class MyWidgetState extends State<MyWidget> {
    List<int> items = [1];

    @override
    Widget build(BuildContext context) {
    return Column(
    children: [
    Row(
    mainAxisAlignment: MainAxisAlignment.center,
    children: [
    IconButton(
    icon: const Icon(Icons.add),
    onPressed: () {
    setState(() {
    items.add(items.last + 1);
    });
    },
    ),
    IconButton(
    icon: const Icon(Icons.delete),
    onPressed: () {
    setState(() {
    if (items.length != 1) items.removeLast();
    });
    },
    ),
    ],
    ),
    for (final item in items)
    MyAnimatedWidget(
    child: SizedBox(
    height: 200,
    child: Center(
    child: Text('Top content item $item'),
    ),
    ),
    ),
    Spacer(),
    Container(
    alignment: Alignment.center,
    decoration: BoxDecoration(border: Border.all()),
    height: 200,
    child: Text('Bottom content'),
    )
    ],
    );
    }
    }

    class MyAnimatedWidget extends StatefulWidget {
    final Widget? child;

    const MyAnimatedWidget({this.child, Key? key}) : super(key: key);

    @override
    State<MyAnimatedWidget> createState() {
    return MyAnimatedWidgetState();
    }
    }

    class MyAnimatedWidgetState extends State<MyAnimatedWidget>
    with SingleTickerProviderStateMixin {
    late AnimationController controller;

    @override
    initState() {
    controller = AnimationController(
    value: 0, duration: const Duration(seconds: 1), vsync: this);
    controller.animateTo(1, curve: Curves.linear);
    super.initState();
    }

    @override
    Widget build(BuildContext context) {
    return AnimatedBuilder(
    animation: controller,
    builder: (context, child) {
    return SizedBox(height: 200 * controller.value, child: widget.child);
    });
    }
    }


    I have tried using a global key to get the size of the spacer and detect after rebuilds whether the spacer has been sized to 0, and if so, re-build the entire widget as a list view (without the spacer) instead of a column. You also need to listen in that case for if the size shrinks and it needs to become a column again, it seemed to make the performance noticeably worse, it was tricky to save the state when switching between column/listview, and it seemed not the best way to solve the problem.

    Any ideas?

    Continue reading...

Compartilhe esta Página