Search code examples
listviewflutterdart

How to pass index from Listview.builder to item widget?


I want to pass the index of listview items within the Listview.builder to delete these items from it in the item widget.

In the class Timeline I'm having a Listview.builder embedded in a Streambuilder.

void removePost(index) {
    setState(() {
      posts.remove(index);
    });
  }

@override
  Widget build(BuildContext context) {
    SizeConfig().init(context);
    return Scaffold(
        body: StreamBuilder<QuerySnapshot>(
          stream: postRef.orderBy('timestamp', descending: false).snapshots(),
          builder: (context, snapshot) {
            if (!snapshot.hasData) {
              return circularProgress();
            }
            List<Post> posts = snapshot.data.documents
                .map((doc) => Post.fromDocument(doc))
                .toList();
            if (posts.isEmpty) {
              return Text("No Posts");
            }
            return ListView.builder(
              itemCount: posts.length,
              itemBuilder: (context, index) {
                final item = posts[index];
                return Post/Item( //??
                  ????? //What comes here? How to pass the index?
                );
              },
            );
          },
        ));
  }

In my class Post the items are build. I want to press the Iconbutton to delete the related post but don't know really how to pass the index.

class Post extends StatefulWidget {
  final int index;
  final String title;
  final String imageUrl;
  final Function(Post) removePost;

  const Post({Key key, this.index, this.title, this.imageUrl, this.removePost})
      : super(key: key);

  factory Post.fromDocument(DocumentSnapshot doc) {
    return Post(
      title: doc['title'],
      imageUrl: doc['imageUrl'],
    );
  }

  @override
  _PostState createState() => _PostState();
}

class _PostState extends State<Post> {
  @override
  Widget build(BuildContext context) {
    SizeConfig().init(context);
    return Container(
      height: SizeConfig.blockSizeHorizontal * (100 / 3 + 3),
      child: Column(
        children: <Widget>[
          Text(widget.title),
          Text(widget.imageUrl),
          IconButton(
            onPressed: () => widget.removePost(this.widget),
            icon: Icon(Icons.delete),
          )
        ],
      ),
    );
  }
}

Any help is appreciated.


Solution

  • @Juju, have you tried,

    return ListView.builder(
                  itemCount: posts.length,
                  itemBuilder: (context, index) {
                    final item = posts[index];
                    return Post(index: index, title: 'Test', imageUrl: 'https://www.google.com',);
                  },
                );
    

    Test:

    class MyApp extends StatefulWidget {
      @override
      MyAppState createState() => MyAppState();
    }
    
    class MyAppState extends State<MyApp> {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
            home: Scaffold(
                appBar: AppBar(
                  title: Text('Test'),
                ),
                body: Container(
                    child: ListView.builder(
                      itemCount: 3,
                      itemBuilder: (context, index) {
                        //final item = posts[index];
                        return Post(index: index, title: 'Test', imageUrl: 'https://www.google.com',);
                      },
                    ),
                )
            )
        );
      }
    }
    
    class Post extends StatefulWidget {
      final int index;
      final String title;
      final String imageUrl;
      final Function(Post) removePost;
    
      const Post({Key key, this.index, this.title, this.imageUrl, this.removePost})
          : super(key: key);
    
    //  factory Post.fromDocument(DocumentSnapshot doc) {
    //    return Post(
    //      title: doc['title'],
    //      imageUrl: doc['imageUrl'],
    //    );
    //  }
    
      @override
      _PostState createState() => _PostState();
    }
    
    class _PostState extends State<Post> {
      @override
      Widget build(BuildContext context) {
        return Container(
          height: 150,
          child: Column(
            children: <Widget>[
              Text(widget.title + ' ' + widget.index.toString()),// Testing passed index here
              Text(widget.imageUrl),
              IconButton(
                onPressed: () => widget.removePost(this.widget),
                icon: Icon(Icons.delete),
              )
            ],
          ),
        );
      }
    }
    

    Screenshot: screenshot