skip to Main Content

I have just started my coding journey in Flutter(Dart). I am trying to design a UI and I have succeeded a little bit but not to my inner peace 😛

So, actually I am trying to design a card like structure in which when I click/tap on it, it should expand and show more data and a button.

Eventually I succeeded using a boolean variable named isExpanded to make changes in height when clicked. But when I tap the container again (Inkwell feature) it shows render flex problem.

So, I want some help from you people, I am just newbie in this, when I get good knowledge, I promise that I will help others too.

So, I need these designs

The design I need

The design when it is clicked, it should expand and when clicked again it shouldn’t show render flex error

The design which I have somehow created lol 😛

Please, give some suggestions or even the code for the required layout, I will be glad for your help

Thank you

2

Answers


  1. You can’t use SizedBox or container for this.

    SizedBox is mainly used to give size between widges

    Container widgets are mainly used as a parent widges where you can implement differnt propertys like color, border radius,… for the child widgets

    What you have to do is:-

    This can be achived in many ways like using animations and all…

    But, I Prefer you to check is ExpansionPanel

    Here, you can expand your card when on tap.

    When using ExpansionPanel you must use ExpansionPanelList

    So, you can make a list of ExpansionPanel.

    Try this code:-

    import 'package:flutter/material.dart';
    
    void main() => runApp(const MyApp());
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      static const String _title = 'Flutter Code Sample';
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: _title,
          home: Scaffold(
            appBar: AppBar(title: const Text(_title)),
            body: const MyStatefulWidget(),
          ),
        );
      }
    }
    
    // stores ExpansionPanel state information
    class Item {
      Item({
        required this.expandedValue,
        required this.headerValue,
        this.isExpanded = false,
      });
    
      String expandedValue;
      String headerValue;
      bool isExpanded;
    }
    
    List<Item> generateItems(int numberOfItems) {
      return List<Item>.generate(numberOfItems, (int index) {
        return Item(
          headerValue: 'Panel $index',
          expandedValue: 'This is item number $index',
        );
      });
    }
    
    class MyStatefulWidget extends StatefulWidget {
      const MyStatefulWidget({Key? key}) : super(key: key);
    
      @override
      State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
    }
    
    class _MyStatefulWidgetState extends State<MyStatefulWidget> {
      final List<Item> _data = generateItems(8);
    
      @override
      Widget build(BuildContext context) {
        return SingleChildScrollView(
          child: Container(
            child: _buildPanel(),
          ),
        );
      }
    
      Widget _buildPanel() {
        return ExpansionPanelList(
          expansionCallback: (int index, bool isExpanded) {
            setState(() {
              _data[index].isExpanded = !isExpanded;
            });
          },
          children: _data.map<ExpansionPanel>((Item item) {
            return ExpansionPanel(
              headerBuilder: (BuildContext context, bool isExpanded) {
                return ListTile(
                  title: Text(item.headerValue),
                );
              },
              body: ListTile(
                  title: Text(item.expandedValue),
                  subtitle:
                      const Text('To delete this panel, tap the trash can icon'),
                  trailing: const Icon(Icons.delete),
                  onTap: () {
                    setState(() {
                      _data.removeWhere((Item currentItem) => item == currentItem);
                    });
                  }),
              isExpanded: item.isExpanded,
            );
          }).toList(),
        );
      }
    }
    

    You will get some idea

    Thank you

    Login or Signup to reply.
  2. Okay you can achieve your goal using ExpandablePanel widget. I have used this package. I have tried something like this. These buildCollapsed(), buildExpanded(), expandedColumn() are custom made function according to your need.

    ExpandablePanel(
      theme: const ExpandableThemeData(
        headerAlignment:
            ExpandablePanelHeaderAlignment.center,
        //tapBodyToExpand: true,
        //tapBodyToCollapse: true,
        hasIcon: false,
      ),
      header: Expandable(
        collapsed: buildCollapsed(), // widget header when the widget is Collapsed
        expanded: buildExpanded(), // header when the widget is Expanded
      ),
      collapsed: Container(), // body when the widget is Collapsed, I didnt need anything here. 
      expanded:  expandedColumn() // body when the widget is Expanded
    ) '
    

    For better understanding, go through the package doc and let me know if you have any question.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search