Анимация CheckBox не работает, когда внутри ReorderableListView - PullRequest
1 голос
/ 15 февраля 2020

Я пытаюсь составить простой список задач, который содержит текст и флажок и позволяет вам переупорядочивать задачи. Все логи c их переупорядочения работают, но при выборе задачи флажок обновляется без запуска анимации.

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

import 'package:flutter/material.dart';

void main() => runApp(MaterialApp(
      title: 'Flutter To Do',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: HomePage(),
    ));

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  List myItems = [];

  @override
  void initState() {
    super.initState();
    for (int i = 0; i < 10; i++) {
      Map<String, dynamic> newTask = Map();
      newTask['task'] = 'Task #$i';
      newTask['done'] = false;
      myItems.add(newTask);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('Flutter To Do'),
        ),
        body: ReorderableListView(
          children: [
            for (final item in myItems)
              Card(
                key: ObjectKey(item),
                margin: EdgeInsets.all(0),
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(0)
                ),
                child: Container(
                  height: 56,
                  child: Row(
                    children: <Widget>[
                      IconButton(icon: Icon(Icons.reorder), onPressed: null),
                      Expanded(
                        child: Text(item['task']),
                      ),
                      Checkbox(
                        value: item['done'],
                        onChanged: (value) {
                          setState(() {
                            item['done'] = value;
                          });
                        },
                      )
                    ],
                  ),
                ),
              )
          ],
          onReorder: (oldIndex, newIndex) {
            setState(() {
              if (newIndex > oldIndex) {
                newIndex -= 1;
              }

              final item = myItems.removeAt(oldIndex);
              myItems.insert(newIndex, item);
            });
          },
        ));
  }
}

1 Ответ

0 голосов
/ 15 февраля 2020

Поскольку setState обновлено ReorderableListView, оно будет повторно отображать весь список, поэтому оно не будет считаться изменением.

, вам следует обновить только один listTile в listView. для этого переместите ваш виджет listTile в виджет Stateful со своим собственным setState и замените свою карту в HomePage:

class _HomePageState extends State<HomePage> {
  List myItems = [];

  @override
  void initState() {
    super.initState();
    for (int i = 0; i < 10; i++) {
      Map<String, dynamic> newTask = Map();
      newTask['task'] = 'Task #$i';
      newTask['done'] = false;
      myItems.add(newTask);
    }
  }

  bool a = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter To Do'),
      ),
      body: ReorderableListView(
        children: [
          for (var item in myItems)
            TaskListItem(
              key: ObjectKey(item),
              item: item,
            ),
        ],
        onReorder: (oldIndex, newIndex) {
          setState(() {
            if (newIndex > oldIndex) {
              newIndex -= 1;
            }

            final item = myItems.removeAt(oldIndex);
            myItems.insert(newIndex, item);
          });
        },
      ),
    );
  }
}
class TaskListItem extends StatefulWidget {
  final item;

  const TaskListItem({Key key, this.item}) : super(key: key);

  @override
  _TaskListItemState createState() => _TaskListItemState();
}

class _TaskListItemState extends State<TaskListItem> {
  @override
  Widget build(BuildContext context) {
    return Card(
      margin: EdgeInsets.all(0),
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(0)),
      child: Container(
        height: 56,
        child: Row(
          children: <Widget>[
            IconButton(icon: Icon(Icons.reorder), onPressed: null),
            Expanded(
              child: Text(widget.item['task']),
            ),
            Checkbox(
              value: widget.item['done'],
              onChanged: (value) {
                setState(() {
                  widget.item['done'] = value;
                });
              },
            )
          ],
        ),
      ),
    );
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...