【问题标题】:How to delete GridView item in flutter?如何在颤动中删除 GridView 项目?
【发布时间】:2019-09-15 01:31:47
【问题描述】:

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

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

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

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")
          )
        )
      ),
    );
  }
}

如何从网格视图中删除项目?
p.s.提供的代码只是我解决问题的尝试 - 如果需要,您可以提供另一种方式!

【问题讨论】:

  • 每次调用 setState 时,都会再次调用构建函数。在该函数中,您循环并创建 10 个新图块。要正确执行此操作,请抽象一个列表来表示列表数据结构并在 initState() 中对其进行实例化
  • @jnblanchard 谢谢,这确实有助于解决这个尴尬的问题!
  • 你这么亲近,给你写答案感觉很奇怪!干得好
  • @jnblanchard 我已经更新了这个问题 - 这几乎是我想要的,但还是有问题.. 你能看一下吗?
  • 看起来你又接近了,我会写一个小例子来说明我如何做到这一点,我想它会让你明白的。我会避免的一件事是将小部件列表作为状态属性。我的想法是对状态进行整数计数,然后构建使用该属性来创建他的单元格。然后,如果您想删除一个单元格,请调用 set state 并减少计数器。逆向也适用于添加单元格

标签: dart flutter


【解决方案1】:

我从示例应用程序中编写了这个,它有一些你可能会发现有用的东西。值得注意的是,我通过在有状态小部件中保存列表的长度来抽象列表数据结构。我用 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))
    );
  }
}

【讨论】:

  • 非常感谢!现在我可以尝试调整您删除任何项目的方法(我想是某种过滤器......)
  • 今天早上hack的时候忘记gridview了,有问题可以告诉我,我再看看
【解决方案2】:

我终于得到了我想要的。
我会把它留给可能有同样问题的人:)

主类:

import 'dart:math';

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 some data
  List<Person> partyInviteList = [];

  _PrototypeState(){
    //filling the list
    for(int i=0; i<5; i++){ 
      partyInviteList.add(Person.generateRandomPerson());
    }
    print("Person ${partyInviteList.toString()}");
  }

  @override
  Widget build(BuildContext context) {
  //----building the app----
  return Scaffold(
      appBar: AppBar(
        title: Text("Prototype"),
        actions: <Widget>[
            IconButton(
              icon: Icon(Icons.add),
              //generating an item on tap
              onPressed: () {
                setState(() {
                  partyInviteList.add(Person.generateRandomPerson());
                });
              },
            ),
          ]
      ),
      body: GridView.count(
      crossAxisCount: 2,
      children: List.generate(partyInviteList.length, (index) {
        //generating tiles with people from list
        return TestTile(
          partyInviteList[index], (){
            setState(() {
              print("person ${partyInviteList[index]} is deleted");
              partyInviteList.remove(partyInviteList[index]);
            });
          }
        );
        })
      )
    ); 
  }
}

///person class
class Person{
  Person(this.firstName, this.lastName);
  static List<String> _aviableNames = ["Bob", "Alise", "Sasha"];
  static List<String> _aviableLastNames = ["Green", "Simpson", "Stain"];

  String firstName;
  String lastName;

  ///method that returns random person
  static Person generateRandomPerson(){
    Random rand = new Random();
    String randomFirstName = _aviableNames[rand.nextInt(3)];
    String randomLastName = _aviableLastNames[rand.nextInt(3)];
    return Person(randomFirstName, randomLastName);
  }

  @override
  String toString() {
    return "$firstName $lastName";
  }
}

支持类:

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

class TestTile extends StatelessWidget{
  final Person person;
  var _callback;

  TestTile(this.person, this._callback);

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

【讨论】:

    猜你喜欢
    • 2022-01-03
    • 1970-01-01
    • 2021-09-15
    • 2019-01-14
    • 1970-01-01
    • 2019-08-04
    • 2020-12-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多