DavideBelsole / great_list_view

pub.dev library for flutter
MIT License
39 stars 21 forks source link

Qn: pass data as props #3

Closed bsr203 closed 3 years ago

bsr203 commented 3 years ago

Thank you for your work on this project.I have slightly different need, where the data is passed as props. Please see the example. Everything works fine, except there is no animation. Any feedback is greatly appreciated. Thanks again. bsr.

Eidt: there is a refresh button on top right (it's blue, so sometimes hard to see :-))which toggles the lists, and diff is notified of change in didUpdateWidget by the parent.

import 'package:flutter/material.dart';

import 'package:great_list_view/great_list_view.dart';
// ignore: import_of_legacy_library_into_null_safe
import 'package:worker_manager/worker_manager.dart' show Executor;

void main() async {
  await Executor().warmUp();
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  late List<MyItem> items;

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

    items = listA;
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Test App',
        theme: ThemeData(
          primarySwatch: Colors.yellow,
          visualDensity: VisualDensity.adaptivePlatformDensity,
        ),
        home: SafeArea(
            child: Scaffold(
          body: Stack(
            children: <Widget>[
              MyListView(items),
              Align(
                alignment: Alignment.topRight,
                child: GestureDetector(
                  onTap: click,
                  child: Icon(
                    Icons.refresh,
                    color: Colors.blue,
                    size: 36.0,
                  ),
                ),
              ),
            ],
          ),
        )));
  }

  void click() {
    setState(() {
      items = swapList ? listB : listA;
    });
    swapList = !swapList;
  }
}

class MyItem {
  final int id;
  final Color color;
  final double? fixedHeight;
  const MyItem(this.id, [this.color = Colors.blue, this.fixedHeight]);
}

List<MyItem> listA = [
  MyItem(1, Colors.orange),
  MyItem(2),
  MyItem(3),
  MyItem(4),
  MyItem(5),
  MyItem(8, Colors.green)
];
List<MyItem> listB = [
  MyItem(2),
  MyItem(6),
  MyItem(5, Colors.pink, 100),
  MyItem(7),
  MyItem(8, Colors.yellowAccent)
];

AnimatedListController controller = AnimatedListController();

class MyComparator extends ListAnimatedListDiffComparator<MyItem> {
  MyComparator._();

  static MyComparator instance = MyComparator._();

  @override
  bool sameItem(MyItem a, MyItem b) => a.id == b.id;

  @override
  bool sameContent(MyItem a, MyItem b) =>
      a.color == b.color && a.fixedHeight == b.fixedHeight;
}

bool swapList = true;

class MyListView extends StatefulWidget {
  final List<MyItem> items;
  MyListView(this.items);

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

class _MyListViewState extends State<MyListView> {
  late ListAnimatedListDiffDispatcher<MyItem> diff;

  @override
  void initState() {
    super.initState();
    diff = ListAnimatedListDiffDispatcher<MyItem>(
      animatedListController: controller,
      currentList: widget.items,
      itemBuilder: buildItem,
      comparator: MyComparator.instance,
    );
  }

  @override
  void didUpdateWidget(covariant MyListView oldWidget) {
    super.didUpdateWidget(oldWidget);

    if (widget.items != oldWidget.items) {
      diff.dispatchNewList(widget.items);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scrollbar(
        child: CustomScrollView(
      slivers: <Widget>[
        AnimatedSliverList(
          delegate: AnimatedSliverChildBuilderDelegate(
            (BuildContext context, int index, AnimatedListBuildType buildType,
                [dynamic slot]) {
              return buildItem(
                  context, diff.currentList[index], index, buildType);
            },
            childCount: () => diff.currentList.length,
            onReorderStart: (i, dx, dy) => true,
            onReorderMove: (i, j) => true,
            onReorderComplete: (i, j, slot) {
              var list = diff.currentList;
              var el = list.removeAt(i);
              list.insert(j, el);
              return true;
            },
          ),
          controller: controller,
          reorderable: true,
        )
      ],
    ));
  }

  Widget buildItem(BuildContext context, MyItem item, int index,
      AnimatedListBuildType buildType) {
    return SizedBox(
        height: item.fixedHeight,
        child: DecoratedBox(
            key: buildType == AnimatedListBuildType.NORMAL
                ? ValueKey(item)
                : null,
            decoration: BoxDecoration(
                border: Border.all(color: Colors.black12, width: 0)),
            child: Container(
                color: item.color,
                margin: EdgeInsets.all(5),
                padding: EdgeInsets.all(15),
                child: Center(
                    child: Text(
                  'Item ${item.id}',
                  style: TextStyle(fontSize: 16),
                )))));
  }
}
federico-amura-kenility commented 3 years ago

any solution to this?

bsr203 commented 3 years ago

No. I switched to diffutil_sliverlist