Flutter/Dart 如何将索引从 Listview.builder 传递到项目小部件

Posted

技术标签:

【中文标题】Flutter/Dart 如何将索引从 Listview.builder 传递到项目小部件【英文标题】:Fluter/Dart How to pass index from Listview.builder to item widget 【发布时间】:2019-12-12 17:44:48 【问题描述】:

我想在 Listview.builder 中传递列表视图项的索引,以便在项小部件中从中删除这些项。

在班级Timeline 我在 Streambuilder 中嵌入了一个 Listview.builder。

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?
                );
              ,
            );
          ,
        ));
  

在我的班级Post 中,项目已构建。 我想按图标按钮删除相关帖子,但不知道如何通过索引。

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),
          )
        ],
      ),
    );
  

感谢任何帮助。

【问题讨论】:

【参考方案1】:

@Juju,你试过了吗,

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

测试:

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),
          )
        ],
      ),
    );
  

截图:

【讨论】:

由于不知道应该构建哪个项目而引发错误。我猜我需要在return语句中实现```final item``` 所以您根本看不到您的列表吗?此外,您的Post 不会占用item,因此除非您更改Post,否则您无法通过它。 查看我编辑的代码,我进行了测试,我的答案似乎工作正常。 是的,这行得通!当您按下图标时,它实际上是在删除该项目吗?我通过return Post(deletePost: deletePost, index: index, title: 'Test', imageUrl: 'https://www.google.com',); 并打电话给IconButton( onPressed: () =&gt; widget.removePost(widget.index), icon: Icon(Icons.delete), ) 并没有任何反应:( 太棒了。请将其标记为答案,以帮助其他有类似问题的人。它不会在我结束时删除,因为我没有你的帖子,但如果你正确传递它应该对你很好。

以上是关于Flutter/Dart 如何将索引从 Listview.builder 传递到项目小部件的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Flutter/Dart 中使用 Hive 框和索引以简单的方式将数据动态加载到 DataTable?

Flutter/Dart:如何访问地图/对象中的单个条目

Flutter/Dart - 如何在其他屏幕上的图像选择器后更新图像

如何从 Flutter(Dart) 中的另一个类调用方法?

在 Flutter/Dart 中从字节加载图像的问题

如何在 Flutter Dart 中实现插件架构