Berechnen Sie den Unterschied zwischen zwei Listen als Liste von Bearbeitungsvorgängen. Zum Beispiel zum impliziten Animieren von Flutter-Listen, ohne ein StatefulWidget beibehalten zu müssen.
Aus öffentlichen Paketdaten erstellte Orientierung.
diffutil_dart berechnet den Unterschied zwischen zwei Listen und generiert eine Folge von Bearbeitungsvorgängen (Einfügen, Löschen, Verschieben), um eine Liste in die andere zu überführen. Dadurch können effiziente, implizite Animationen in Flutter-Listen realisiert werden, ohne den Zustand in StatefulWidget-Widgets manuell verwalten zu müssen. Es ist besonders nützlich zum Aktualisieren von Benutzeroberflächen mit minimalen Neuerzeugungen, was Leistung und Reaktionsfähigkeit bei dynamischen Daten verbessert. Das Paket ist leichtgewichtig und kompatibel mit allen Hauptplattformen, die von Flutter unterstützt werden.
Anwendungsfälle
Animation von Listenupdates in Flutter
Listenänderungen effizient synchronisieren
Unnotwendige Widget-Rebuilds reduzieren
Glatte Scroll-Übergänge implementieren
Aktualisieren dynamischer Datenquellen
Zustandsverwaltung für Listen vereinfachen
Hauptmerkmale
Generiert präzise Bearbeitungsvorgänge
Unterstützt Einfüge-, Lösch- und Verschiebevorgänge
Minimale Neuerstellung für bessere Leistung
Plattformübergreifende Kompatibilität
Leichtgewichtig und einfach zu integrieren
Keine manuelle Zustandsverwaltung erforderlich
Geeignet für
Entwickler, die Flutter mit dynamischen Listen verwenden
Teams, die reibungslose UI-Animationen priorisieren
Apps mit häufigen Listenaktualisierungen
Diejenigen, die Boilerplate beim Listenhandling reduzieren möchten
Projekte mit Fokus auf leistungsstarkes Listenrendering
Hinweise
Erfordert Verständnis der Bearbeitungsoperationlogik
Am besten geeignet für einfache Listenstrukturen
Kann komplexe verschachtelte Daten nicht optimieren
Nicht ideal für nicht-listen Datentypen
Beschränkt auf Listen-zu-Listen-Vergleiche
Behandelt keine tiefe Gleichheit standardmäßig
Original-README
Originaler README-Schnappschuss aus dem verknüpften Quell-Repository. Aktuelle Inhalte finden Sie im Repository.
diffutil.dart
Calculate the difference between two lists.
Heavily inspired bei Android's DiffUtil class, the code was adopted for Dart.
Uses Myers algorithm internally. For an explanation of how the algorithm works internally, for details I recommend this great series of articles: https://blog.jcoglan.com/2017/02/12/the-myers-diff-algorithm-part-1/
What is this good for?
There are often situations, where an app displays a list of items, which are fetched from an external data source like a server endpoint or a database, and updates are not
sent as delta, but as a whole new list.
It can be useful to take the old list and the new list and calculate the difference between those two, for example when animating the insertion and removal of new
items in the displayed list (See diffutil_sliverlist).
This package does exactly that:
It takes two lists and calculates the difference (or to be more accurate: edit script) between those two lists as list of Insert, Remove, Change (only when using custom delegates) and Move (when enabled) operations.
Usage
Calculating diffs:
Simple usage:
final diffResult = calculateListDiff<int>([1, 2 ,3], [1, 3, 4]);
If you don't want to use plain old Dart lists (for example if you're using built_value or kt.dart), and don't want to convert your custom list
to standard lists, you can use
the calculateDiff function and implement your own DiffDelegate easily.
Or use calculateCustomListDiff and CustomListDiffDelegate.
Move detection is disabled by default.
Using the result:
Call .getUpdates() on the diffResult to get a List of DiffUpdate objects. These are sealed classes of type Insert, Remove, Change or Move.
Move operations are only calculated if calculateListDiff was called with detectMoves: true
The order of these operations matters! They describe how to turn the previous list into the new list, when applied in
the order as they are returned.
for (final update in diffResult.getUpdates())
update.when(
insert: (pos, count) => print("inserted $count on $pos"),
remove: (pos, count) => print("removed $count on $pos"),
change: (pos, payload) => print("changed on $pos with payload $payload"),
move: (from, to) => print("move $from to $to"),
);
By default, Insert and Remove Operations are batched. (e.g. multiple consecutive inserts or removes are represented by a single Insert/Remove object with a count field > 1).
If you want to turn off edit script batching, call getUpdates(batch: false).
This means, every Insert and Remove operation will have a count of 1 and the edit script of [] and [1, 2] will be
The result of getUpdatesWithData() cannot be batched.
You can use the resulting Iterable<DataDiffUpdate> like this:
for (final update in updates) {
update.when(
insert: (pos, data) => print('insert $pos$data'),
remove: (pos, data) => print('remove $pos$data'),
change: (pos, oldData, newData) => print('change on $pos from $oldData to $newData'),
move: (from, to, data) => print('move $data from $from to $to'),
);
}
Note that if you implement you own DiffDelegate and call calculateDiff() directly, the
DiffDelegate also needs to implement IndexableItemDiffDelegate if you want to call getUpdatesWithData().
Change Operations
For data objects that have some meaningful identity (like an unique id field), you can enable the calculation of Change operations.
For this, you need to implement your own DiffDelegate and override the areItemsTheSame method.
Let's say we have a class called DataObject which is defined like this: