Flutter撤销重做功能插件undo_redo的使用

发布于 1周前 作者 bupafengyu 来自 Flutter

Flutter撤销重做功能插件undo_redo的使用

undo_redo

undo_redo pub points pub package

这是一个简单的且功能强大的Dart包,提供了易于使用的撤销和重做功能,并带有额外的便捷方法。无论你是处理简单的原始类型还是复杂的对象,此包都能帮助你轻松实现撤销/重做功能。

平台

Android iOS MacOS Web Linux Windows

Demo

探索在线web演示以查看该包的实际应用。

Basic example using integers Deep copy example using list Deep copy example using custom object

开始使用

在你的Flutter项目的pubspec.yaml文件中,添加以下依赖:

dependencies:
  ...
  undo_redo: <latest>

导入它:

import 'package:undo_redo/undo_redo.dart';

使用

示例1:撤销/重做与原始类型

使用原始类型管理状态变化非常直接:

final UndoRedoManager<int> _undoRedoManager = UndoRedoManager<int>();

[@override](/user/override)
void initState() {
  _undoRedoManager.initialize(0); // 初始状态
  super.initState();
}

void _incrementCounter() {
  _counter++;
  _undoRedoManager.captureState(_counter); // 捕获新状态
  setState(() {});
}

// 撤销上一个操作
int? undoData = _undoRedoManager.undo();

// 重新执行上一个撤销的操作
int? redoData = _undoRedoManager.redo();

// 重置到初始状态
int? initialData = _undoRedoManager.clearHistory();

// 检查是否可以撤销
bool canUndo = _undoRedoManager.canUndo();

// 检查是否可以重做
bool canRedo = _undoRedoManager.canRedo();

示例2:撤销/重做与非原始类型

对于列表

当你处理非原始类型如对象或集合时,必须使用深拷贝以确保状态变更是独立的:

// 这是指向同一内存位置
List<int> ages = originalAges; 
// 这是一个深拷贝,不是同一引用
List<int> ages = List.from(originalAges); 

对于自定义对象

扩展Cloneable类以提供深拷贝方法:

class Staff extends Cloneable<Staff> {
  String name;
  List<int> ratings;

  [@override](/user/override)
  Staff clone() {
    return Staff(
      name: name,
      ratings: List.from(ratings),
    );
  }
}

或者

如果你已经继承了一个类,可以使用CloneableMixin

class Staff extends People with CloneableMixin<Staff> {
  ...
}

现在,你可以管理复杂对象的撤销/重做:

final UndoRedoManager<Staff> _undoRedoManager = UndoRedoManager<Staff>();
Staff _staff = Staff(name: 'Foo Bar', ratings: [2, 3, 5]);

[@override](/user/override)
void initState() {
  _undoRedoManager.initialize(_staff.clone()); // 捕获初始状态
  super.initState();
}

void _onValueChange() {
  _undoRedoManager.captureState(_staff.clone()); // 捕获新状态
  setState(() {});
}

// 撤销上一个操作
void undo() {
  var undoData = _undoRedoManager.undo();
  if (undoData != null) {
    _staff = undoData.clone(); // 恢复到先前状态
  }
}

更多关于Flutter撤销重做功能插件undo_redo的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter撤销重做功能插件undo_redo的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter应用中使用undo_redo插件来实现撤销和重做功能的示例代码。undo_redo插件允许你管理命令历史记录,从而轻松实现撤销和重做功能。

首先,你需要在pubspec.yaml文件中添加undo_redo依赖:

dependencies:
  flutter:
    sdk: flutter
  undo_redo: ^2.0.0  # 请检查最新版本号

然后运行flutter pub get来安装依赖。

接下来是一个简单的示例,展示如何使用undo_redo插件:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Undo/Redo Example'),
        ),
        body: UndoRedoExample(),
      ),
    );
  }
}

class UndoRedoExample extends StatefulWidget {
  @override
  _UndoRedoExampleState createState() => _UndoRedoExampleState();
}

class _UndoRedoExampleState extends State<UndoRedoExample> {
  final _controller = TextEditingController();
  final _undoRedo = UndoRedo<String>();

  void _addText(String text) {
    setState(() {
      _undoRedo.add(
        () => _controller.text, // Save current text state
        () => _controller.text = text, // Command to execute
      );
    });
  }

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          TextField(
            controller: _controller,
            maxLines: 5,
            decoration: InputDecoration(
              border: OutlineInputBorder(),
              labelText: 'Enter text',
            ),
          ),
          SizedBox(height: 16),
          ElevatedButton(
            onPressed: () {
              _addText(_controller.text + ' new line');
            },
            child: Text('Add New Line'),
          ),
          SizedBox(height: 8),
          ElevatedButton(
            onPressed: _undoRedo.canUndo ? () => _undoRedo.undo() : null,
            child: Text('Undo'),
          ),
          SizedBox(height: 8),
          ElevatedButton(
            onPressed: _undoRedo.canRedo ? () => _undoRedo.redo() : null,
            child: Text('Redo'),
          ),
        ],
      ),
    );
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }
}

在这个示例中:

  1. UndoRedo<String>实例_undoRedo用于管理撤销和重做命令。
  2. _addText方法添加一个新的命令到历史记录中。这个命令保存当前的文本状态,并将文本更新为新的内容。
  3. UI包含一个TextField用于输入文本,以及三个按钮:一个用于添加新行,一个用于撤销,另一个用于重做。
  4. 撤销和重做按钮的onPressed回调分别调用_undoRedo.undo()_undoRedo.redo(),并根据是否可以撤销或重做来启用或禁用按钮。

通过这种方式,你可以轻松地在Flutter应用中实现撤销和重做功能。

回到顶部