Проблема с использованием пакета Provider во Flutter - PullRequest
0 голосов
/ 03 августа 2020

main.dart

void main() {
  runApp(ToDo());
}

class ToDo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider(
          create: (context) => TaskList(),
        ),
      ],
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        home: TaskPage(),
        theme: ThemeData.dark().copyWith(
          canvasColor: Colors.transparent,
        ),
      ),
    );
  }
}

Я использую два Consumer Widget, один возвращает виджет Text , а другой возвращает виджет ListView .

class TaskPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Color(0xff212121),
      body: Container(
        padding: EdgeInsets.only(top: 50),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            ListTile(
              leading: CircleAvatar(
                radius: 25,
                backgroundColor: Colors.white,
                child: Icon(
                  Icons.check,
                  color: Colors.black,
                  size: 40,
                ),
              ),
              title: Text(
                'ToDo',
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 50,
                  fontWeight: FontWeight.w900,
                ),
              ),
            ),
            SizedBox(
              height: 40,
            ),
            Center(
              child: Consumer<TaskList>(
                builder: (context, list, child) {
                  print('making new text');
                  return Text(
                    '${list.length} Tasks  Remaining',
                    style: TextStyle(
                      color: Colors.white,
                      fontSize: 20,
                    ),
                  );
                },
              ),
            ),
            Expanded(
              child: Container(
                child: Consumer<TaskList>(
                  builder: (context, list, child) {
                    return ListView(
                      children: list.taskList,
                    );
                  },
                ),
                decoration: BoxDecoration(
                  color: Colors.white,
                  borderRadius: BorderRadius.only(
                    topLeft: Radius.circular(30.0),
                    topRight: Radius.circular(30.0),
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(
          Icons.add,
          color: Colors.white,
        ),
        backgroundColor: Colors.blueGrey,
        onPressed: () {
          showModalBottomSheet(
            context: context,
            builder: (context) => AddTaskSheet(),
          );
        },
      ),
    );
  }
}

Объект, который я хочу предоставить этим виджетам, - это TaskList, содержащий список.

class TaskList with ChangeNotifier {
  List<TaskTile> taskList = [
    TaskTile(taskData: TaskData(task: 'Code')),
    TaskTile(taskData: TaskData(task: 'Code Again')),
    TaskTile(taskData: TaskData(task: 'Keep Coding')),
  ];

  int get length => taskList.length;

  void addTask(TaskTile newTaskTile) {
    taskList.add(newTaskTile);
    notifyListeners();
  }

}

Чтобы добавить задачу, я используя ModalBottomSheet, который содержит:

class AddTaskSheet extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    String newTask;
    return Container(
      color: Colors.transparent,
      child: Container(
        padding: EdgeInsets.all(20),
        decoration: BoxDecoration(
          color: Color(0xff212121),
          borderRadius: BorderRadius.only(
            topRight: Radius.circular(40.0),
            topLeft: Radius.circular(40.0),
          ),
        ),
        child: Column(
          children: <Widget>[
            TextField(
              onChanged: (value) {
                newTask = value;
              },
              decoration: InputDecoration(
                hintText: 'Describe Your Task',
                hintStyle: TextStyle(
                  color: Colors.white38,
                ),
                fillColor: Colors.black,
                filled: true,
                enabledBorder: OutlineInputBorder(
                  borderSide: BorderSide(color: Colors.white),
                  borderRadius: BorderRadius.all(Radius.circular(30)),
                ),
                focusedBorder: OutlineInputBorder(
                  borderSide: BorderSide(color: Colors.white, width: 2.5),
                  borderRadius: BorderRadius.all(Radius.circular(30)),
                ),
              ),
            ),
            SizedBox(height: 30),
            AddButton(
              onTap: () {
                print(newTask);
                Provider.of<TaskList>(context, listen: false).addTask(
                  TaskTile(
                    taskData: TaskData(task: newTask),
                  ),
                );
                Navigator.pop(context);
              },
            ),
          ],
        ),
      ),
    );
  }
}

Здесь я добавил кнопку с именем AddButton в AddTaskSheet :

import 'package:flutter/material.dart';

class AddButton extends StatelessWidget {
  final Function onTap;
  AddButton({this.onTap});
  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: onTap,
      child: Container(
        child: ListTile(
          contentPadding: EdgeInsets.symmetric(horizontal: 60),
          title: Text(
            'ADD NEW TASK',
            style: TextStyle(
              color: Colors.white70,
              fontWeight: FontWeight.bold,
            ),
          ),
          leading: Icon(
            Icons.add,
            color: Colors.white70,
          ),
        ),
        decoration: BoxDecoration(
          color: Colors.black,
          borderRadius: BorderRadius.all(
            Radius.circular(30),
          ),
          boxShadow: <BoxShadow>[
            BoxShadow(
              color: Colors.black38,
              blurRadius: 5.0,
              offset: Offset(-5.0, 15.0),
            )
          ],
        ),
      ),
    );
  }
}

Теперь, когда я добавляю новая задача в моем списке, тогда даже после вызова notifyListener ListView не обновляется новой задачей, но, с другой стороны, виджет Text обновляется с новым размером списка.

Я не знаю, что не так. Может кто-нибудь, пожалуйста, помогите.

...