skip to Main Content

I want to create a custom itemBuilder for a widget that I am creating as it needs to have dynamic widgets for each use case.

How can I implement something like ListView.builder(itemBuilder: ...)‘s item builder for my widget?

I tried creating a function as a parameter to get it to work but I was stuck after getting the function, I didn’t know how to iterate through it.

class ViewClass extends StatelessWidget{
    ViewClass({
        this.key, 
        required this.itemBuilder,
    });

    final Function(Widget item) itemBuilder;
    @override
    Widget build(BuildContext context) {
        return Container(...);   
    }
}

2

Answers


  1. from what i understand,you trying to create a custom widget from a list view item if so you could do it like below. Note i am using a list of string as items as an example but you can use any Objects. kindly correct me if this is not what you are trying to do:

    class ViewClass extends StatelessWidget {
      const ViewClass({
        super.key,
        required this.item,
      });
    
      final String item;
      @override
      Widget build(BuildContext context) {
        return Container(
          child: Text(item),
        );
      }
    }
    
    class MyListClass extends StatelessWidget {
      MyListClass({super.key});
      List<String> itemList = ["item 1", "item 2", "item 3"];
      @override
      Widget build(BuildContext context) {
        return ListView.builder(
          itemCount: itemList.length,
          itemBuilder: (context, index) {
            var item = itemList[index];
            return ViewClass(item: item);
          },
        );
      }
    }
    
    Login or Signup to reply.
  2. Flutter is open source, you could just try to look into ListView.builder‘s source code (by control clicking it from your IDE) to look how it’s done, but there’s an even much simpler widget: Builder. It’s probably the simplest widget that has such a feature. So simply look how they do it. And that’s:

    class Builder extends StatelessWidget {
      /// Creates a widget that delegates its build to a callback.
      const Builder({
        super.key,
        required this.builder,
      });
    
      /// Called to obtain the child widget.
      ///
      /// This function is called whenever this widget is included in its parent's
      /// build and the old widget (if any) that it synchronizes with has a distinct
      /// object identity. Typically the parent's build method will construct
      /// a new tree of widgets and so a new Builder child will not be [identical]
      /// to the corresponding old one.
      final WidgetBuilder builder;
    
      @override
      Widget build(BuildContext context) => builder(context);
    }
    

    And here WidgetBuilder is defined as:

    typedef WidgetBuilder = Widget Function(BuildContext context);
    

    So what you did wrong is actually you defined itemBuilder as a Function that takes a widget as argument, but you needed one that returns it. So you could do this for example:

    class ViewClass extends StatelessWidget{
      const ViewClass({
        super.key,
        required this.itemBuilder,
      });
    
      final Widget Function() itemBuilder;
      @override
      Widget build(BuildContext context) {
        return Container(child: itemBuilder());
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search