Dividing a long list of Widgets into multiple pages - flutter

Let's say I have a list of widgets as follows :
List<Widget> widgets = [Row(1), Row(2), Row(3), ...... Row(30)];
Now I want to divide this list into multiple pages. Something like this :
PageView(
children: [
Page1(), // lets say this page contains rows 1 to 7
Page2(), // lets say this page contains rows 8 to 13
Page3(), // this contains the remaining rows 14 - 30
]
)
Now this would have been somewhat easy to solve if all the rows were of same height.
But in my case, the heights of the row can vary.
The issue is I have no idea about how many rows to fit in each page as flutter doesn't provide any good way to calculate the height of a widget.
Any suggestions on how to approach this problem will be appreciated.

If I understood your problem correctly, maybe you don't need separate pages.
I guess something like this would help:
var rowSet1 = [Row(), Row(), Row()];
var rowSet2 = [Row(), Row(), Row()];
var rowSet3 = [Row(), Row(), Row()];
var pageView = PageView(children: [
...rowSet1,
...rowSet2,
...rowSet3
]);
You can even split it into separate files, but just reference/import it and use in the file where you need it.
You can make a RowWrapper widget that would receive Row as a child, but it would be wrapped with a Container with fixed height or IntrinsicHeight (if you want to let the framework decide the height).

Related

How to create something like this ? flutter

How to create something like this I hardcode this and it's image slideshow `
ImageSlideshow(
children: [
MFeaturesCard1(mWidth: mWidth, mHeight: mHeight),
MFeaturesCard2(mWidth: mWidth, mHeight: Height),
],
),
when I swipe right it gives some thing like this and each children has 2 row each row has 3 features card so 1 children has 6 features card
1st children - 0-5,
2nd children - 6-11,
3rd children - 12-18 I want like this but I want to fetch this from API and generate this widget
this is how I fetch my features

Flutter - Cells spannable table view

I just looking for a widget type where it provides a simple default solution to draw shared border lines between children widgets, instead of touching two different borders or turning a widget into a border. Basically it's just a table thing with the children as it's cell widgets.
There's Table in Flutter. But sadly seems like the cells is unspannable. No "colspan" thing for it's TableCell. If I put TableRows with different numbers of TableCells, I get error
Table contains irregular row lengths. Every TableRow in a Table must
have the same number of children, so that every cell is filled.
Otherwise, the table will contain holes.
I used to do it with Java.
<TableLayout ...>
<TableRow ...>
<... android:layout_span .../>
</TableRow>
</TableLayout>
I just want to do it again with Flutter. That's all.
ListView.separated might be what you are looking for
It takes the following arguments
itemBuilder for the content of your rows
separatorBuilder for creating a dynamic separator between your cells. You could use the Divider widget for that purpose.
Solved by simply put inner table inside outer table's cell.
Table(
children : [
TableRow( //This row will contains virtually spanned cell
children: [
TableCell(...),
],
),
TableRow( //This row will contains indirectly unspanned cells
children: [
TableCell(
child : Table(...),
),
],
)
]
);
And then remove outer borders for inner table leaving only inner borders.
TableBorder(
horizontalInside : BorderSide(
color : Colors.grey,
),
verticalInside : BorderSide(
color : Colors.grey,
),
)
I don't know whether it's a workaround or just how Flutter deal with it because I got the answer from Flutter's github

Flutter Table layout is not responding according to expected

Using Flutter v1.20.2
The following code
var data = [
['a', 'VerylongstringwithnospacesVerylongstringwithnospaces'],
['abc', '123456789'],
['abcdefg', '123'],
];
Expanded(
child: Table(
border: TableBorder.all(color: Colors.red),
columnWidths: {
0: IntrinsicColumnWidth(),
1: IntrinsicColumnWidth(),
},
children: data.map<TableRow>((x) => (
TableRow(
children: <TableCell>[
TableCell(child: Container(child: Text(x[0]))),
TableCell(child: Container(color: Colors.green, child: Text(x[1]))),
],
)
)).toList(),
),
),
results in this layout
As you can see the text overflows the boundary of the table.
I have tried innumerable solutions but none have worked. It appears that the TableCell itself has a width bigger than it should have, comparing to the size of the column of the table.
The biggest problem is that the size of both columns are unknown, they could be hundreds of characters long or single letter. In case of it being bigger than the width the text should break to the next line.
Is there a way to make a fluid grid layout so that both sides resize according to the amount of content for each Column? The ideal layout would be something like this
The reason why It’s happening is that the IntrinsicColumnWidth doesn’t give TableCell parent size. Because it's trying to set the column width based on child width. At the same time, to make text wrapping on lines, you need to have the width of parent, otherwise text widget don’t know it’s limits.
What options do you have :
FixedColumnWidth
FlexColumnWidth
FractionColumnWidth
MaxColumnWidth
MinColumnWidth
(Last two widgets used max/min of other TableColumnWidth widgets.)
In your case if you know that the text in the first column never will need to be wraped in lines, you can remove IntrinsicColumnWidth as parameter of second column. If you know that long text is possible, add the maximum width by adding MinColumnWidth
dartpad example

Flutter row, align items individually in cross axis

In a row widget, with the crossAxisAlignment: CrossAxisAlignment.center property, all the widgets inside of the row will be vertically centred inside the Row, as expected.
But how do I do if I want only one of them aligned for exmample to the start, something like the picture below:
I can think of some ways to do it, like adding a Column in the last widget, and play with the main axis aligment, Expanded...etc etc but seems like a lot of boilerplate code for such a simple output, ther might be out there a simpler and more elegant way to achieve this??
You can wrap widget 4 in a Container and set the height as widget 3 and add Alignment.topCenter
Ah, stumbled across this and found a solution.
Wrap widgets 3 and 4 in another Row and set the inner Row to CrossAxisAlignment.start.
Row(
children: [
LargeWidget('w1'),
LargeWidget('w2'),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LargeWidget('w3'),
SmallWidget('w4'),
],
),
],
);
This frees you from having to know the height of each widget.

How to make Wrap to not minimise height (reduce number of rows) as much as possible

I'm trying to build a "semi-responsive" widget. It has a fixed number of relatively large children that always fit on the screen horizontally (A, B and C) and a variable list of small children that not always fit horizontally together with A, B, and C. My idea is to have the widget look like the first picture when the screen is wide, and as a second when the screen is more narrow, and as a third when there's no space for smaller widgets at all. What I'm getting is the third only. As if Wrap always tries to put as many children horizontally as possible. I want it to minimize width instead.
My pseudocode:
Card(
child: Wrap(
children: [
Row(children: [A(), B(), C()]),
Wrap(children: [1(), 2(), 3(), 4(), 5()]),
]
),
);
Any idea how to "squeeze" Wrap vertically? Using standard layout widgets if possible.
You can archive that using the alignment property in the Wrap widget.
Card(
child: Wrap(
alignment: WrapAlignment.end,
children: [
Row(children: [A(), B(), C()]),
1(), 2(), 3(), 4(), 5(),
],),
);
check it out in dartpad gist