Juju
Juju

Reputation: 449

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.

Upvotes: 2

Views: 10474

Answers (1)

Pro
Pro

Reputation: 3003

@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

Upvotes: 3

Related Questions