diffutil_dart는 두 목록 간의 차이를 계산하고 하나의 목록을 다른 목록으로 변환하기 위한 편집 작업(삽입, 삭제, 이동) 시퀀스를 생성합니다. 이를 통해 StatefulWidget 위젯에서 상태를 수동으로 관리하지 않고도 Flutter 리스트에서 효율적이고 암시적인 애니메이션을 가능하게 합니다. 특히 동적 데이터를 다룰 때 최소한의 재구성으로 UI를 업데이트하여 성능과 반응성을 향상시키는 데 특히 유용합니다. 이 패키지는 가볍고 Flutter가 지원하는 모든 주요 플랫폼과 호환됩니다.
사용 사례
Flutter에서 목록 업데이트 애니메이션화
목록 변경 사항을 효율적으로 동기화합니다
불필요한 위젯 재구성 줄이기
스무스 스크롤 전환 구현
동적 데이터 소스 업데이트
리스트의 상태 관리를 단순화하기
주요 기능
정밀한 편집 작업을 생성합니다
삽입, 삭제 및 이동 작업을 지원합니다
더 나은 성능을 위한 최소 재빌드
크로스 플랫폼 호환성
경량이며 통합이 쉬움
수동 상태 관리 필요 없음
적합한 대상
동적 목록을 사용하는 Flutter 개발자
부드러운 UI 애니메이션을 우선시하는 팀
자주 목록이 업데이트되는 앱
리스트 처리에서 반복 코드를 줄이고자 하는 사람
고성능 리스트 렌더링을 목표로 하는 프로젝트
고려 사항
편집 작업 로직에 대한 이해가 필요합니다
간단한 목록 구조에 가장 적합
복잡한 중첩된 데이터를 최적화하지 않을 수 있습니다
리스트가 아닌 데이터 유형에는 적합하지 않음
리스트 간 차이 비교에 제한됨
기본적으로 깊은 동등성을 처리하지 않습니다
원본 README
연결된 소스 저장소의 README 원문 스냅샷입니다. 최신 내용은 저장소에서 확인하세요.
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: