Expand flutter datatable row on click - flutter

I'm currently using a DataTable to display a summary of some data like this
DataTable(
showCheckboxColumn: false,
columns: columnNames,
rows: state.alerts.alerts
.map(
(alert) => DataRow(
cells: [
const DataCell(Icon(
Icons.circle,
color: Colors.amber,
)),
const DataCell(Text("Something"),),
const DataCell(Text("Something")),
const DataCell(Text("TO DO")),
DataCell(Text(DateTime.fromMillisecondsSinceEpoch(alert.time.toInt(), isUtc: true).toString())),
],
onSelectChanged: (bool? selected) {
if (selected == null || !selected) return;
// Show details
},
),
)
.toList())
Which looks something like this
I would like to have it so when a user selects a row, that row expands vertically and shows additioal information whilst still part of the table (i.e. all rows below the selected row should be pushed down). The functionality I'd like to achieve is exactly what https://api.flutter.dev/flutter/material/ExpansionPanelList-class.html is intended for however using that would mean I loose access to the advantages of using a table (automated column sizing etc).
Is there a way I can create a custom table row without copying the entire DataTable source out and modifying how rows are generated?
^EDIT: After looking into the source of DataTable this doesn't look like a viable option, DataTable ultimatly mashes everything into a Table which enforces column widths. The only work around I can think of would be creating a new table for each row so a non tabled widget can be inserted in between but this would likely break a lot of stuff and be horrible for performance.
Expandable row in table with flutter- is it possible? looks like a step in the right direction however much like the OP, I can't see a way to apply Expandable to a TableRow rather than a TableCell
Thanks

Related

How to switch between widgets in a table? Flutter

I need your help. I have a table with data in explorer_screen, when you click on each line, it goes to the corresponding page with detailed information about the block block_info_screen. So I need to add the ability to switch between these blocks, which are in the table on the details page. So that you can not return to the table and select another block, but immediately switch from block_info_screen to the elements following the table. As far as I understand, I need to wrap each row in the table in a push widget and use buttons and Navigator.push to switch between these widgets from the block_info_screen page.
Could you elaborate more on how to implement this feature?
explorer_screen - here is the table
return DataTable(
columns: const [
DataColumn(label: Text('Height')),
DataColumn(label: Text('Hash')),
DataColumn(label: Text('Time')),
],
rows: List.generate(5, (index) {
return DataRow(cells: [
DataCell(TextButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => BlockInfoPage(
hashBlock: blocksData[index].hash,
heightBlock:
'${blocksData[index].height}',
)));
},
child: Text('${blocksData[index].height}'))),
DataCell(Text(blocksData[index].hash)),
DataCell(Text('${blocksData[index].time}')),
]);
}));
block_info_screen - here is detailed information and here you need to implement switching between data in the table
return Column(children: [
_blockInfo(blocksInfoData),
const SizedBox(height: 20),
_blockDetails(blocksInfoData),
]);
Buttons to be implemented on the details page
Here is my table and when I click on each element I get a page with detailed information. You have to switch between them.
What you can do is you can send your whole list to the next screen i.e block screen and also the current index of the data cell that is selected. So initially you can display the selected element and then you can manage/change your index on next and back buttons as you have the access to the whole list.
If it's tough to understand.. let me know I'll elaborate.. but i would suggest you to try this out first. 🥇

Flutter grouped listview by first word

I currently have a ListView that displays a large collection of objects. Quite a lot of these objects share the same first one/two words, for example:
Peter Johnson
Peter Jackson
Peter Smith
I would like to split this ListView into groups based on the start of their names. So for example all the Peters would be put in the same group. And then the next name that multiple people share would also be split into their own group.
The problem is that I can't explicitly say what these names are, how would I go about splitting these up?
This is a hard one, I'm going to try to simplify this as much as possible, but the general answer is first write an algorithm that splits your string how you want (in this case, if the first word is the same) and then nest these into a column or whatever.
Here I split the values into a map with the first name as a key and a list of all the people with that first name as a value
// Theres probably a better way to do this
Map<String, List<String>> valuesByFirstName(List<String> values) {
Map<String, List<String>> result = {};
for (final val in values) {
final fn = val.split().first;
if (result[fn] != null) result[fn]!.add(val);
else result[fn] = [val];
}
return result;
}
Then I'm not sure how you wanna group each of these so I just made some basic example:
var values = valuesByFirstName(originalValues);
return Row(
children: [
for (var key in values.keys)
SizedBox(
height: 200,
width: 100,
child: ListView(
children: [
Text(key, style: TextStyle(fontSize: 20)),
for (var value in values[key])
Text(value),
]
),
),
),
],
);
If what you want is to contract the different sections, take a look at the ExpansionPanel widget

Is there a way to automatically wrap widgets within a row

Sorry if this is a dup, I see a lot of questions regarding text wrapping, but not generic widget wrapping in a row.
I have a dynamic row of buttons within a row. I'd like to wrap the buttons to create a second row if the list becomes longer than the width of the screen. Is it possible to do this automatically, or do I need to manually detect and create the correct number of rows.
If the latter, does anybody have pointers to measuring a widget's width vs screen width? Right now I'm doing something like:
...
return Row(
children: List.generate(count*2 + 1, (i) {
if (i %2 == 0) {
return Spacer();
}
return RaisedButton(child: Text((i / 2).round().toString(), onPressed: (){...});
});
Row is useful when you need to organize child widgets in a single line. Wrap with default direction is an alternative to Row that moves child widgets to the next line if there is no enough space

How to align item in list view side by side in flutter?

My Requirements is to arrange items like this in listview:
item 1 item2
item 3 item4
item 5 item6
I'm currently using ListView and its children as Wrap widget(to arrange item in next line)
My Output is like this
item 1 item 4
item 2 item 5
item 3 item 6
How to achieve my requirement in the flutter
The best way to do this is by using GridView. It is really meant for that kind of layout that you needed.
Here is an example of how to use a GridView:
GridView.count(
// Create a grid with 2 columns. If you change the scrollDirection to
// horizontal, this produces 2 rows.
crossAxisCount: 2,
// Generate 100 widgets that display their index in the List.
children: List.generate(100, (index) {
return Center(
child: Text(
'Item $index',
style: Theme.of(context).textTheme.headline5,
),
);
}),
);
Here is a picture showing the layout difference between GridView and ListView:
#Uni answerd to use Grid-view, and that's 100% correct, but if you need a setup like this:
--Widget1-- --Widget2--
--------Widget3--------
--Widget4-- --Widget5--
You could use Listview, but then have the Widget1 and Widget2 in a Row(), And that way there will only be 1 widget(Row) on each line, but that widget(Row) will have 2 child-widgets, or more, on the inside.
This gives a lot more flexibility than Gridview, but to be honest if you need the function of gridview, then use that, I even use it, but Listview with rows can be helpfull for a more dynamic design :)

How to create Tree View Layout in Flutter?

I am making a screen when I need to show design like Screen Below, with tree views and connectors.
It will be a great help if someone can suggest me how to create a design like this, conceptually.
I have tried a Gridview and tree_view so far.
GridView.count(
// Create a grid with 2 columns. If you change the scrollDirection to
// horizontal, this produces 2 rows.
crossAxisCount: 2,
// Generate 100 widgets that display their index in the List.
children: List.generate(100, (index) {
return Center(
child: Text(
'Item $index',
style: Theme.of(context).textTheme.headline,
),
);
}),
);
Use the public flutter package called GraphView
Flutter GraphView is used to display data in graph structures. It can
display Tree layout, Directed and Layered graph. Useful for Family
Tree, Hierarchy View.
The library is designed to support different graph layouts and currently works excellent with small graphs.
graphite is somewhat similar to the design,
DirectGraph(
list: list,
cellWidth: 136.0,
cellPadding: 24.0,
orientation: MatrixOrientation.Vertical,
)