Невозможно удалить в onDismissible

У меня есть код, который использует отключенные в списке (показывает элементы из базы данных). После отклонения элемента предполагается, что закусочная будет отображаться, но она не отображается, и кажется, что отклоняемый элемент все еще является частью дерева. Вы можете мне с этим помочь?

return ListView.builder(
  itemCount: count,
  itemBuilder: (BuildContext context, int position) {
    final ThemeData theme = Theme.of(context);

    return Dismissible(

      key: Key(this.objs[position].id.toString()),
      onDismissed: (direction) {
        setState(() async {
          int result = await helper.delete(this.objs[position].id);
        });
        Scaffold.of(context)
            .showSnackBar(SnackBar(
            content: Text(this.objs[position].title + "dismissed")));
      },
      background: Container(
          color: Colors.red,
          child: const ListTile(
              leading: Icon(Icons.delete, color: Colors.white, size: 36.0)
          )
      ),

      child: ListTile(
        leading: CircleAvatar(
          backgroundColor: getColor(this.objs[position].priority),
          child: Text(this.objs[position].id.toString()),
        ),
        title: Text(obj[position].title),
        subtitle: Text(objs[position].date),
        onTap: () {
          debugPrint("Tapped on " + objs[position].id.toString());
          navigateToDetail(this.objs[position]);
        },
      ),
    );
  },
);

это называется внутри эшафота. А objs - это список, содержащий все мои объекты из базы данных.

Вот мой код удаления, который вызывается внутри onDismissed:

    Future<int> delete(int id) async {
    Database db = await this.db;
    var result = await db.rawDelete("DELETE FROM $tblT WHERE $colId=$id");
    return result;
  }

Я заметил, удаляю ли я один элемент и сразу же пытаюсь создать другой (у меня есть возможность вставить в БД): иногда возникает ошибка: отклоненный виджет «Отклоняемый» все еще является частью дерева

Обновление: перемещена часть удаления до setState, и я получаю сообщение об ошибке: отклоненный виджет Dismissible по-прежнему является частью дерева каждый раз, когда я смахиваю, чтобы закрыть


person Roya    schedule 09.10.2018    source источник


Ответы (2)


Вы можете попробовать следующий код для свойства onDismissed:.

Проблема в будущем внутри функции onDismissed. Нам нужно изменить порядок ключевых слов async и await.

В любом случае, будьте осторожны с таймингом при удалении следующих друг за другом элементов.

onDismissed: (direction) async {
    String title = this.obj[position].title;
    await helper.delete(this.obj[position].id);
    setState(() {});
    Scaffold.of(context)
       .showSnackBar(SnackBar(content: Text("$title dismissed")));
},

Он также перемещает асинхронный код из setState() и сохраняет заголовок, который будет использоваться позже SnackBar.

person chemamolins    schedule 09.10.2018
comment
Благодарю. но в этом случае возникает ошибка, заключающаяся в том, что отклоненный виджет с возможностью отклонения все еще является частью дерева. @chemamolins - person Roya; 09.10.2018
comment
Вы можете попробовать две вещи: сначала избавиться от асинхронного поведения, а затем получить доступ к Scaffold через GlobalKey. Я отредактировал свой ответ, чтобы отразить это. - person chemamolins; 09.10.2018
comment
Вы имеете в виду, что я не могу использовать тип Future? Я использую его и в других частях своего кода, для асинхронного поведения - person Roya; 09.10.2018
comment
Да, вы можете использовать фьючерсы, но я не уверен, следует ли его использовать для удаления элемента списка, который поддерживает ListView. Боюсь, что проблема, с которой вы столкнулись, связана со сроками. Например, если вы обращаетесь к элементам непосредственно в this.obj[position].title, возможно, вы могли бы напрямую получить доступ к списку, чтобы удалить их. - person chemamolins; 09.10.2018
comment
Я использовал: obj.removeAt (position); (obj - это список) вместо удаления из db. И после этого оператора я удаляю его из базы данных, но при этом получаю сообщение об ошибке: Было выбрано другое исключение: 'package: flutter / src / widgets / framework.dart': Неудачное утверждение: строка 4051 pos 14: '_dependents. isEmpty ': неверно. I / flutter (18171): Возникло другое исключение: в дереве виджетов обнаружен дублирующийся GlobalKey. - person Roya; 09.10.2018
comment
Думаю, я воспроизвел вашу проблему с помощью будущего. В моем случае это было решено с помощью приведенного выше фрагмента. Я изменил ответ. - person chemamolins; 10.10.2018
comment
В моем случае это показывает ошибку, что запрещенный виджет все еще является частью дерева. - person Roya; 10.10.2018
comment
Важно, чтобы setState () вызывалась после ожидания. Полученная ошибка похожа на вызов setState() без ожидания и без удаления элемента в списке (просто попробуйте полностью удалить строку helper.delete...). - person chemamolins; 10.10.2018
comment
То есть я уже внес изменения, о которых вы упомянули. удаление перед вызовом setState. Но все же мне говорят, что отклоненный виджет с возможностью отклонения все еще является частью дерева - person Roya; 10.10.2018
comment
Я имею в виду, что setState () должен вызываться, когда мы полностью уверены, что объект в списке был удален. Если setState () вызывается до фактического удаления объекта, мы получаем ошибку. - person chemamolins; 10.10.2018
comment
У вашего кода такой же порядок и ключевые слова async и await, как указано выше? Если так, то я не знаю, что еще я могу сделать. - person chemamolins; 10.10.2018
comment
Да, такой же порядок. но по-прежнему имеет проблему, что отклоненное отклоненное все еще является частью дерева - person Roya; 10.10.2018

Внутри содержимого SnackBar вы можете попробовать:

Text(this.obj[position].title.toString() + "dismissed")
person yashthakkar1173    schedule 09.10.2018
comment
title - это строковый тип - person Roya; 09.10.2018