so I am trying to build a multi platform table for my flutter project. But when the row count gets larger than a few hundred, the scrolling geht's extremely laggy, especially in a web application. The build process also takes almost 5 seconds. To build the tab I use a Column with identical build Rows inside a SingleChildScrollView. The Table class of Flutter has the same issue and I couldn't find a working package on pub.dev jet.
Even in a Project where only this Table exists, the scrolling is not acceptable. What can I do to build a large row count like 1000 or more with a smooth scrolling?
Here is the simplified code:
import 'package:flutter/material.dart';
class MyTable extends StatefulWidget{
@override
State<MyTable> createState() => _MyTableState();
}
class _MyTableState extends State<MyTable> {
final double columnSpace = 5;
final double rowSpace = 5;
final decoration = BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: Colors.grey,
);
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Column(
children: List.generate(1000, (index) => _buildRow(index)),
),
);
}
_buildRow(int index){
return Column(
children: [
SizedBox(
height: 40,
child: Row(
children: [
_buildExpandedCell(10, index.toString()),
SizedBox(width: rowSpace,),
_buildExpandedCell(4, index.toString()),
SizedBox(width: rowSpace,),
_buildExpandedCell(3, index.toString()),
SizedBox(width: rowSpace,),
_buildExpandedCell(3, index.toString()),
SizedBox(width: rowSpace,),
_buildExpandedCell(3, index.toString()),
SizedBox(width: rowSpace,),
Container(
decoration: decoration,
width: 90,
),
],
),
),
SizedBox(height: columnSpace,),
],
);
}
_buildExpandedCell(int flex, String content){
return Expanded(
flex: flex,
child: Container(
height: double.infinity,
decoration: decoration,
child: Center(child: Text(content)),
),
);
}
}
CodePudding user response:
You should use a ListView.builder
instread of a Column
For your example that would be instead of
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Column(
children: List.generate(1000, (index) => _buildRow(index)),
),
);
}
do
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: 1000,
itemBuilder: (context, index) => _buildRow(index),
);
}
The reason is that Column
s load all children in memory, even the non-visible ones. With a ListView.builder
it only loads the ones that are visible on screen.
CodePudding user response:
You can try using ListView.builder(...)
. Column with children has to paint all children, regardless of that if child is visible on screen or not, while listview.builder
paint only visible children few extra for smooth scrolling.