skip to Main Content

I am trying to build a custom version of a column (call it CustomColumn) that lays out the children lazily, similar to what a ListView would do but with more control on how exactly they are laid out. The most basic point I am stuck on is: How can I create a widget while in the performLayout phase of the CustomColumn. I am struggling to find a minimal example on how to do that. The only other widget I could find that does something like this is ListView but I could not create a minimal version of that.

During layout, I am trying to check the available space and, only if needed create a child (using an IndexedWidgetBuilder) and lay that out. I suppose that there should a functionality like ‘adoptChild’ or ‘discardChild’ to manage the child widget’s lifecycle, but I could not find the correct API for that.

I am specifically not interested in scrolling, debug overflow painting, or anything beyond just dynamic (or lazy) widget creation during layout (for now). What could be the minimal set of classes needed to achieve this behaviour?

2

Answers


  1. Without having a look at code it gonna be little hard to answer exact solution.I think you need to create 2 widgets first named as CustomColumn second you need LayoutWidget. some thing like that.

       class CustomLazyColumn extends RenderObjectWidget {
      final IndexedWidgetBuilder builder;
      final int itemCount;
    
      CustomLazyColumn({
        Key? key,
        required this.builder,
        required this.itemCount,
      }) : super(key: key);
    
      @override
      RenderObject createRenderObject(BuildContext context) {
        return CustomLazyColumnRenderObject(
          builder: builder,
          itemCount: itemCount,
        );
      }
    
      @override
      void updateRenderObject(
          BuildContext context, CustomLazyColumnRenderObject renderObject) {
        renderObject
          ..builder = builder
          ..itemCount = itemCount;
      }
    }
    

    after that use this rendering part

        class CustomLazyColumnRenderObject extends RenderBox
        with ContainerRenderObjectMixin<RenderBox, LazyColumnParentData> {
      IndexedWidgetBuilder builder;
      int itemCount;
    
      CustomLazyColumnRenderObject({
        required this.builder,
        required this.itemCount,
      });
    
      double _currentOffset = 0.0;
    
      @override
      void performLayout() {
        double usedHeight = 0.0;
        double maxWidth = 0.0;
    
        RenderBox? child = firstChild;
    
        for (int index = 0; index < itemCount; index++) {
          if (usedHeight >= constraints.maxHeight) break;
    
          if (child == null) {
            // Create the child lazily
            final newChild = builder(null, index).createRenderObject(context!);
            adoptChild(newChild);
            insert(newChild);
            child = newChild;
          }
    
          child.layout(constraints, parentUsesSize: true);
    
          final childParentData = child.parentData as LazyColumnParentData;
          childParentData.offset = Offset(0, _currentOffset);
    
          _currentOffset += child.size.height;
          usedHeight += child.size.height;
          maxWidth = maxWidth.max(child.size.width);
    
          child = childAfter(child);
        }
    
        size = constraints.constrain(Size(maxWidth, usedHeight));
      }
    
      @override
      void paint(PaintingContext context, Offset offset) {
        RenderBox? child = firstChild;
        while (child != null) {
          final childParentData = child.parentData as LazyColumnParentData;
          context.paintChild(child, offset + childParentData.offset);
          child = childAfter(child);
        }
      }
    
      @override
      void setupParentData(RenderBox child) {
        if (child.parentData is! LazyColumnParentData) {
          child.parentData = LazyColumnParentData();
        }
      }
    }
    

    class LazyColumnParentData extends ContainerBoxParentData {}

    hopefully it gonna help

        CustomLazyColumn(
      itemCount: 1000,
      builder: (context, index) {
        return Text('Item $index', style: TextStyle(fontSize: 18));
      },
    );
    
    Login or Signup to reply.
  2. You want Boxy:

    Boxy is a Flutter package created to overcome the limitations of built-in layout widgets, it provides utilities for flex, custom multi-child layouts, dynamic widget inflation, slivers, and more!

    The package is ready for production use, it has excellent documentation, test coverage, and passes strict analysis.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search