如何使列表视图构建器在颤振中成为可重新排序的列表视图(优先任务应用程序(待办事项应用程序))

Posted

技术标签:

【中文标题】如何使列表视图构建器在颤振中成为可重新排序的列表视图(优先任务应用程序(待办事项应用程序))【英文标题】:how can make listview builder to a reorderable listview in flutter (a priority task app (todo app)) 【发布时间】:2021-09-16 20:26:52 【问题描述】:

如何将 listview 转换为 reorderedableListview 以制作优先任务应用程序

这是我的应用程序设计输出

我看到了很多解决方案,但在大多数解决方案中我发现了错误

这是初始化状态代码

    class _TodoListScreenState extends State<TodoListScreen> 
      late List<Task> taskList = [];
    
      @override
      void initState() 
        super.initState();
        _updateTaskList();
      
    
      _updateTaskList() async 
        print('--------->update');
        this.taskList = await DatabaseHelper.instance.getTaskList();
        print(taskList);
        setState(() );
      

这是创建listtile的方法

    
      Widget _buildTask(Task task) 
        return Column(
          children: [
            Padding(
              padding: const EdgeInsets.symmetric(horizontal: 25.0),
              child: ListTile(
                title: Text(
                  task.title!,
                  style: TextStyle(
                    fontSize: 18.0,
                    decoration: task.status == 0
                        ? TextDecoration.none
                        : TextDecoration.lineThrough,
                  ),
                ),
                subtitle: Text(
                  '$DateFormat.yMMMEd().format(task.date!) • $task.priority',
                  style: TextStyle(
                    fontSize: 18.0,
                    decoration: task.status == 0
                        ? TextDecoration.none
                        : TextDecoration.lineThrough,
                  ),
                ),
                trailing: Checkbox(
                  onChanged: (value) 
                    task.status = value! ? 1 : 0;
                    DatabaseHelper.instance.updateTask(task);
                    _updateTaskList();
                  ,
                  value: task.status == 1 ? true : false,
                  activeColor: Theme.of(context).primaryColor,
                ),
                onTap: () => Navigator.push(
                  context,
                  MaterialPageRoute(
                    builder: (context) => AddTask(
                      task: task,
                      updateTaskList: () 
                        _updateTaskList();
                      ,
                    ),
                  ),
                ),
              ),
            ),
            Divider(),
          ],
        );
      
    


这是方法构建

      @override
      Widget build(BuildContext context) 
        return Scaffold(
          floatingActionButton: FloatingActionButton(
            child: Icon(Icons.add),
            backgroundColor: Theme.of(context).primaryColor,
            onPressed: () => Navigator.push(
              context,
              MaterialPageRoute(
                builder: (context) => AddTask(updateTaskList: _updateTaskList),
              ),
            ),
          ),

在这个body标签中我想创建可重新排序的列表视图

          body: ListView.builder(
            padding: EdgeInsets.symmetric(vertical: 80.0),
            itemCount: taskList.length + 1,
            itemBuilder: (BuildContext context, int index) 
              if (index == 0) 
                return Padding(
                  padding:
                      const EdgeInsets.symmetric(horizontal: 40.0, vertical: 20.0),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Text(
                        "My Tasks",
                        style: TextStyle(
                            fontWeight: FontWeight.bold,
                            fontSize: 40.0,
                            color: Colors.black),
                      ),
                      SizedBox(height: 15.0),
                      Text(
                        '$taskList.length of $taskList.where((Task task) => task.status == 1).toList().length task complete ',
                        style: TextStyle(
                          fontWeight: FontWeight.w600,
                          fontSize: 20.0,
                          color: Colors.grey,
                        ),
                      ),
                    ],
                  ),
                );
               else 
                return _buildTask(taskList[index - 1]);
              
            ,
          ),
        );
      
    

这是我要更改的整个代码

【问题讨论】:

【参考方案1】:

您可以使用像ReorderableListView 这样的小部件和像Reorderables 这样的库。

更新

示例代码:

import 'dart:math';

import 'package:flutter/material.dart';
import 'package:reorderables/reorderables.dart';

class ReorderablesImagesPage extends StatefulWidget 
  ReorderablesImagesPage(
    Key key,
    this.title,
    @required this.size,
  ) : super(key: key);

  final String title;
  final double size;

  @override
  State<StatefulWidget> createState() => _ReorderablesImagesPageState();


class _ReorderablesImagesPageState extends State<ReorderablesImagesPage> 
  List<Widget> _tiles;

  int maxImageCount = 30;

  double iconSize;

  final int itemCount = 3;
  final double spacing = 8.0;
  final double runSpacing = 8.0;
  final double padding = 8.0;

  @override
  void initState() 
    super.initState();

    iconSize = ((widget.size - (itemCount - 1) * spacing - 2 * padding) / 3)
        .floor()
        .toDouble();

    _tiles = <Widget>[
      Container(
        child: Image.network('https://picsum.photos/250?random=1'),
        width: iconSize,
        height: iconSize,
      ),
      Container(
        child: Image.network('https://picsum.photos/250?random=2'),
        width: iconSize,
        height: iconSize,
      ),
      Container(
        child: Image.network('https://picsum.photos/250?random=3'),
        width: iconSize,
        height: iconSize,
      ),
      Container(
        child: Image.network('https://picsum.photos/250?random=4'),
        width: iconSize,
        height: iconSize,
      ),
      Container(
        child: Image.network('https://picsum.photos/250?random=5'),
        width: iconSize,
        height: iconSize,
      ),
      Container(
        child: Image.network('https://picsum.photos/250?random=6'),
        width: iconSize,
        height: iconSize,
      ),
      Container(
        child: Image.network('https://picsum.photos/250?random=7'),
        width: iconSize,
        height: iconSize,
      ),
      Container(
        child: Image.network('https://picsum.photos/250?random=8'),
        width: iconSize,
        height: iconSize,
      ),
      Container(
        child: Image.network('https://picsum.photos/250?random=9'),
        width: iconSize,
        height: iconSize,
      ),
    ];
  

  @override
  Widget build(BuildContext context) 
    void _onReorder(int oldIndex, int newIndex) 
      setState(() 
        Widget row = _tiles.removeAt(oldIndex);
        _tiles.insert(newIndex, row);
      );
    

    var wrap = ReorderableWrap(
        minMainAxisCount: itemCount,
        maxMainAxisCount: itemCount,
        spacing: spacing,
        runSpacing: runSpacing,
        padding: EdgeInsets.all(padding),
        children: _tiles,
        onReorder: _onReorder,
        onNoReorder: (int index) 
          //this callback is optional
          debugPrint(
              '$DateTime.now().toString().substring(5, 22) reorder cancelled. index:$index');
        ,
        onReorderStarted: (int index) 
          //this callback is optional
          debugPrint(
              '$DateTime.now().toString().substring(5, 22) reorder started: index:$index');
        );

    var column = Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[
        Expanded(
          child: SingleChildScrollView(
            child: wrap,
          ),
        ),
        ButtonBar(
          buttonPadding: EdgeInsets.all(16),
          alignment: MainAxisAlignment.end,
          children: <Widget>[
            if (_tiles.length > 0)
              IconButton(
                iconSize: 50,
                icon: Icon(Icons.remove_circle),
                color: Colors.teal,
                padding: const EdgeInsets.all(0.0),
                onPressed: () 
                  setState(() 
                    _tiles.removeAt(0);
                  );
                ,
              ),
            if (_tiles.length < maxImageCount)
              IconButton(
                iconSize: 50,
                icon: Icon(Icons.add_circle),
                color: Colors.deepOrange,
                padding: const EdgeInsets.all(0.0),
                onPressed: () 
                  var rand = Random();
                  var newTile = Container(
                    child: Image.network(
                        'https://picsum.photos/250?random=$rand.nextInt(100)'),
                    width: iconSize,
                    height: iconSize,
                  );
                  setState(() 
                    _tiles.add(newTile);
                  );
                ,
              ),
          ],
        ),
      ],
    );

    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: column,
    );
  

【讨论】:

我做了,但我发现了很多错误,所以你能提供代码我该怎么做 我更新了答案。试着理解这个过程。

以上是关于如何使列表视图构建器在颤振中成为可重新排序的列表视图(优先任务应用程序(待办事项应用程序))的主要内容,如果未能解决你的问题,请参考以下文章

Flutter:如何在列表视图中通过拖放对项目进行排序?

如何使用颤振使列表视图滚动 360

如何从列表视图中删除某些内容并重新加载页面?颤振网络

如何在颤振/飞镖中缓存列表视图构建器?

Flutter - 可重新排序的列表,Listview 嵌套在 expandtile 内

如何在飞镖/颤振中按日期对列表进行排序/排序?