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 :P
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 which I have somehow created lol :P
Please, give some suggestions or even the code for the required layout, I will be glad for your help
Thank you
CodePudding user response:
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 useExpansionPanelList
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
CodePudding user response:
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.