Home > Net >  Flutter columns scrolling gets very laggy with higher row counts
Flutter columns scrolling gets very laggy with higher row counts

Time:07-07

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 Columns 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.

Check this link

  • Related