Виджет Flutter Stateful не перестраивается

заранее спасибо за вашу помощь, у меня есть приложение, которое в основном является приложением TODO, проблема здесь в том, что у меня есть список типа String, в котором пользователь будет помещать задачи, которые ему нужно выполнить, и именно поэтому я попытаться сделать, это проверить, когда список все еще пуст, показать столбец с изображением, и если пользователь добавляет элемент, список больше не пуст, поэтому он показывает список, а не столбец, для этого я сделал просто если в методе buildscreen() . Проблема: виджет после добавления нового элемента в мой список не перестраивается снова даже после вызова setState в addTask() и поэтому не видит, полный список или пустой и продолжает показывать столбец с изображением.

Вот код

 import 'package:flutter/material.dart';
import 'package:todo_app/custom_icons_icons.dart';

class Todo extends StatefulWidget {
  @override
  _TodoState createState() => _TodoState();
}

List<String> tasks = [];
var hour= DateTime.now().hour;
int listlength= tasks.length;



class _TodoState extends State<Todo> {
  GlobalKey<AnimatedListState> globalKey= new GlobalKey<AnimatedListState>();
  void addTask(String text){
    print("Add task is built");
    setState(() {
      tasks.insert(0,text);
      globalKey.currentState.insertItem(0);


    });



  }

  void removeTask(int index){
setState(() {
  globalKey.currentState.removeItem(index, (context,animation){
    return SizedBox(width: 0, height: 0);

  });
  tasks.removeAt(index);

});
  }

  Widget promptRemove(int index){
    showDialog(context: context,
    builder: (BuildContext builder){
     return AlertDialog(
       title: Text("Do you want to mark ${tasks[index]} as done?"),
       actions: [
          FlatButton(onPressed:() {
            removeTask(index);
            Navigator.pop(context);
          }
              , child: Text("Mark as Done")),
         FlatButton(onPressed:(){
           Navigator.pop(context);
         }, child: Text("Cancel"))

       ],
      );
    }
    );
  }

  Widget buildItem(String text, int index){
    return Dismissible(
      key: Key("${text.hashCode}"),
      onDismissed: (direction)=> removeTask(index),
      direction: DismissDirection.startToEnd,
      child: Card(
        elevation: 4,
        child: ListTile(
          leading: Container(
              margin: EdgeInsets.only(
                top: 5
              ),
              child: Container(

                  child: Icon(Icons.lightbulb, size: 30, color: Colors.blue,))),
          title: Text(text),
          subtitle: Text("Today"),
          trailing: Icon(Icons.arrow_forward_ios_rounded, color: Colors.blue,),
        ),
      ),
    );
  }
  
  Widget buildList(){
    return AnimatedList(
      key: globalKey,
      initialItemCount: tasks.length,
      itemBuilder: (BuildContext context, int index, animation){
        return SlideTransition(
            position: Tween<Offset>(
              begin: const Offset(-1, 0),
              end: Offset(0, 0),
            ).animate(CurvedAnimation(
                parent: animation,
                curve: Curves.bounceIn,
                reverseCurve: Curves.bounceOut)),
            child: buildItem(tasks[index], index));
        }
        );
    
  }
  Widget buildscreen(){
    print("Screen is built");
    if (tasks.isEmpty){
      return Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Container(
              child: Image.asset("assets/images/3327598.jpg"),
            ),
            Text("Add tasks and start beign producivity "),
            SizedBox(height: 100,)
          ],
        ),
      );
    }else{
      return buildList();
    }

  }

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        centerTitle: true,
        elevation: 0,
        backgroundColor: Colors.transparent,
        actions: [
          ((){
            if (hour>6 && hour<18){
              return Container(
                  margin: EdgeInsets.only(
                    right: 20
                  ),
                  child: Icon(CustomIcons.cloud_sun, color: Colors.blue,size: 28,));
            } else {
              return Container(
                  margin: EdgeInsets.only(
                    right: 20
                  ),
                  child: Icon(CustomIcons.cloud_moon, color: Colors.blue,size: 28,));

            }

          }())
        ],
        leading: Container(
          width: 10,
          height: 10,
          margin: EdgeInsets.only(
            top: 10,
            left: 10,
            right: 10,
            bottom: 10
          ),
          decoration: BoxDecoration(
            color: Colors.blue,
            borderRadius: BorderRadiusDirectional.circular(30)
          ),
          child: Center(child: Text("${tasks.length}")),
        ),
        title: Text("Todo App",style: TextStyle(color: Colors.blue),),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed:(){
          Navigator.of(context).push(
            new MaterialPageRoute(builder: (BuildContext context){
              return Scaffold(
                backgroundColor: Colors.white,
                appBar: AppBar(

                  title: Text("Add a task"),
                ),
                body: TextField(
                  onSubmitted:(val){
                    addTask(val);
                    Navigator.of(context).pop();


                  },
                ),
              );
            })
          );
        },
        child: Icon(Icons.add),
      ),
      body: buildscreen()


      );
  }
}
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
322
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема в том, что вы не проверяете, является ли ваш globalKey.currentState нулевым, прежде чем анимировать введение нового элемента в виджете AnimatedList. Просто добавьте следующую проверку перед вставкой в ​​globalKey.currentState.insertItem(0).

if (globalKey.currentState != null)

Это гарантирует, что вы не будете вставлять элемент, пока виджет перестраивается, и вы будете ждать, пока состояние не станет доступным. После добавления этой строки ваш метод addTask() должен выглядеть так:

  void addTask(String text) {
    print("Add task is built");
    setState(() {
      tasks.insert(0, text);
      if (globalKey.currentState != null) globalKey.currentState.insertItem(0);
    });
  }

Спасибо, это решило мою проблему, но мне нужно больше понять, в чем была проблема, если вы можете объяснить это мне, я не понял, что вы пытаетесь мне сказать.

Ahmed 13.12.2020 19:30

Вам нужно дождаться перестроения элемента, прежде чем вы сможете добавить его в globalKey.currentState.

bluenile 13.12.2020 19:31

Хорошо, я понял, у меня есть еще один вопрос, возможно ли, что это также произошло с моим приложением, я попытался создать горизонтальное представление списка, и оно работает отлично, но дочерний элемент этого представления списка занимает всю высоту представления списка, даже когда Я поставил термоусадочную пленку true, и даже когда дочерний контейнер имеет значение высоты.

Ahmed 13.12.2020 19:33

Я должен буду увидеть код. Но я думаю, что если высота контейнера установлена, то он не должен расширяться, чтобы занять все доступное пространство. Если ListView у вас не работает, вы можете попробовать ScrollableRow. Я прошу вас поставить лайк / проголосовать за принятый ответ. Спасибо

bluenile 13.12.2020 19:55

Спасибо :) Я проверю ваше предложение

Ahmed 13.12.2020 20:41

Другие вопросы по теме