dart - 如何在 flutter 中删除 GridView 项目?

标签 dart flutter

我正在尝试通过长按动态删除简单的网格项目;

我尝试了最明显的方法:创建一个网格数据列表,并在添加或删除项目时调用 setState。

UPD: 项目在列表中正常工作,因为它的初始化循环移动到 initState() 方法(正如@jnblanchard 在他的评论中所说),并且不要在每次 build() 调用时都不会生成新项目,但删除仍然不起作用。
如果它有更多的项目,超过了屏幕,它删除最后一行(当删除了足够多的项目时),否则抛出以下异常:

I/flutter (28074): The following assertion was thrown during performLayout():
I/flutter (28074): SliverGeometry is not valid: The "maxPaintExtent" is less than the "paintExtent".
I/flutter (28074): The maxPaintExtent is 540.0, but the paintExtent is 599.3. By definition, a sliver can't paint more
I/flutter (28074): than the maximum that it can paint!

我现在的测试代码:

主类

import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:options_x_ray_informer/prototyping/TestTile.dart';

class Prototype extends StatefulWidget{
  @override
  _PrototypeState createState() => _PrototypeState();
}

class _PrototypeState extends State<Prototype> {
  //list of grid data
  List<Widget> gridItemsList = [];

  @override
  void initState(){
    super.initState();
    //----filling the list----
    for(int i =0; i<10; i++){
      gridItemsList.add(
        TestTile(i, (){
          //adding callback for long tap
          delete(i);
        })
      );
    }
  } 

  @override
  Widget build(BuildContext context) {
  //----building the app----
  return Scaffold(
      appBar: AppBar(
        title: Text("Prototype"),
        actions: <Widget>[
            IconButton(
              icon: Icon(Icons.add),
              onPressed: () {
                int index = gridItemsList.length+1;
                add(
                  new TestTile(index, (){
                    delete(index);
                  })
                );
              },
            ),
          ]
      ),
      body: GridView(
        gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
        children: gridItemsList
      )
    ); 
  }

  ///method for adding the items
  void add(Widget toAdd){
    setState(() {
      TestTile tile = toAdd as TestTile; 
      gridItemsList.add(toAdd);
      print("tile number#${tile.index} added");
    });
  }

  ///method for deleting the items 
  void delete(int index){
    setState(() {
      gridItemsList.removeAt(index);
      print("tile number#$index is deleted");
    });
  }
}

单独的小部件类用于网格项

import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';

class TestTile extends StatelessWidget{
  int _index;
  var _callback;

  TestTile(this._index, this._callback);

  get index => _index;

  @override
  Widget build(BuildContext context) {
    return GridTile(
      child: Card(
        child: InkResponse(
          onLongPress: _callback,
          child: Center(
            child:Text("data#$_index")
          )
        )
      ),
    );
  }
}

如何从 GridView 中删除项目?
附:提供的代码只是我解决问题的尝试 - 如果需要,您可以提供另一种方法!

最佳答案

这是我根据示例应用编写的,它包含一些您可能会觉得有用的东西。值得注意的是,我通过将列表的长度保存在有状态的小部件中来抽象列表数据结构。我用 ListView 编写了此代码,但我认为您可以毫无问题地将其更改为 GridView。

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        primarySwatch: Colors.indigo,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  @override
  Widget build(BuildContext context) {

    return Scaffold(appBar: AppBar(
        title: Text("Owl"),
        actions: <Widget>[IconButton(icon: Icon(Icons.remove), onPressed: () => this.setState(() => _counter > 1 ? _counter-- : _counter = 0)), IconButton(icon: Icon(Icons.add), onPressed: () => this.setState(() => _counter++))],
      ),
      body: ListView.builder(itemExtent: 50, itemCount: _counter, itemBuilder: (context, index) => Text(index.toString(), textAlign: TextAlign.center, style: Theme.of(context).textTheme.title))
    );
  }
}

关于dart - 如何在 flutter 中删除 GridView 项目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55852294/

相关文章:

android - Onesignal坚持不懈

来自另一个屏幕的 Flutter 更新状态

使用 DateFormat 处理 HTTP 日期字符串

flutter - 在 Flutter 应用程序中全局使用 asset 文件夹

dart - 如何根据另一个流的事件返回一个流

flutter - flutter 设定事件的频率

flutter - 我首先要打开 ExpansionTile 的项目默认值。我想当我点击另一个项目时,当前项目将关闭。我该怎么做?

loops - For循环在Dart中表现怪异。我试图做一个异步功能来检索数据

json - 解析 dart 中的对象(未处理的异常 : type '_InternalLinkedHashMap<dynamic, dynamic>' is not a subtype of type 'Map<String, dynamic>' )

dart - 所有小部件上的 Flutter 工具提示