Optimizing industrial data displays in Flutter: a deep dive into ListView.Builder and custom RenderObjects

Jan 17, 2024

Werner Scholtz

ListView.builder(
  itemCount: widget.items.length,
  itemExtent: 24.0,
  itemBuilder: (context, index) {
    final data = widget.items[index];
    return DataTile(
      data: data,
    );
  },
),

Widget build(BuildContext context) {
  // Generate the text widgets for each field.
  final columns = data.columns.indexed.map(
    (e) {
      if (e.$1 == 0) {
        // The first column is the id, so give it a fixed width. 
        return SizedBox(
          width: 52,
          child: Text(e.$2),
        );
      }
      return Text(e.$2);
    },
  ).toList();

  return Row(
    mainAxisAlignment: MainAxisAlignment.spaceBetween,
    children: columns,
  );
}

This content can not be viewed with respect to your privacy. Allow statistics and marketing in your or view on YouTube.

class CustomDataTile extends LeafRenderObjectWidget {
  const CustomDataTile({
    super.key,
    required this.data,
  });
 
  final Data data;
 
  
  RenderObject createRenderObject(BuildContext context) {
    return CustomDataRenderObject(data: data);
  }
 
  
  void updateRenderObject(
    BuildContext context,
    CustomDataRenderObject renderObject,
  ) {
    renderObject.data = data;
  }
}
final double idWidth = 52;

/// The width of the field text painters.
double get fieldTextPainterWidth =>
      (constraints.maxWidth - idWidth) / numberOfItems;


void performLayout() {
  // Layout the text painters.
  for (var i = 0; i < _textPainters.length; i++) {
    if (i == 0) {
      // Layout the id text painter, with a fixed width.
      _textPainters[i].layout(maxWidth: idWidth);
    } else {
      // Layout the field text painters.
      _textPainters[i].layout(maxWidth: fieldTextPainterWidth);
    }
  }

  // Use the full width of the constraints.
  final width = constraints.maxWidth;

  // Use the height of the first text painter.
  final height = _textPainters.first.height;

  // Set the size of this render object.
  size = constraints.constrain(
    Size(width, height),
  );
}

void paint(PaintingContext context, Offset offset) {
  // Loop through the text painters and paint them.
  for (var i = 0; i < _textPainters.length; i++) {
    final textPainter = _textPainters[i];
    if (i == 0) {
      // Paint the id text painter at the offset.
      textPainter.paint(context.canvas, offset);
    } else {
      // Calculate the x position for the field text painter.
      final textPainterX = idWidth + (fieldTextPainterWidth * i);

      // Calculate the offset for the field text painter.
      final textPainterOffset = Offset(textPainterX, 0) + offset;

      // Paint the field text painter.
      textPainter.paint(context.canvas, textPainterOffset);
    }
  }
}
ListView.builder(,
  itemExtent: 24.0,
  itemCount: widget.items.length,
  itemBuilder: (context, index) {
    final data = widget.items[index];
    return CustomDataTile(
      data: data,
    );
  },
),

This content can not be viewed with respect to your privacy. Allow statistics and marketing in your or view on YouTube.

Leave a Comment

Your Email address will not be published