DavideBelsole / great_list_view

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

AutomaticAnimatedListView grey tint when reorderModel specified #38

Open asaiahdev777 opened 1 year ago

asaiahdev777 commented 1 year ago

I am using the AutomaticAnimatedListView, and when the reorderModel is set to something other than null, I get this behaviour where the list items have a greyish background. Why is this?

class BrowseListView extends StatelessWidget {
  final BrowseMode mode;

  const BrowseListView({Key? key, required this.mode}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final list = mode.decksToList.toList();
    return Scrollbar(
      child: AutomaticAnimatedListView(
        list: list,
        listController: context.read<MainViewModel>().listController,
        itemBuilder: (context, item, data) =>
            data.measuring ? nothing : BrowseItemWidget(item, list),
        comparator: AnimatedListDiffListComparator<DeckListItem>(
          sameItem: (a, b) => a.runtimeType == b.runtimeType && a.id == b.id,
          sameContent: (a, b) => false,
        ),
        addLongPressReorderable: true,
        reorderModel: AutomaticAnimatedListReorderModel(list),
      ),
    );
  }
}

class BrowseItemWidget extends StatelessWidget {
  final DeckListItem item;
  final List<DeckListItem> items;

  const BrowseItemWidget(this.item, this.items, {super.key});

  @override
  Widget build(BuildContext context) {
    final model = context.read<MainViewModel>();
    return Column(
      children: [
        ListTile(
          //leading: leading(context, model),
          title: title(context),
          subtitle: subtitle(context),
          trailing: checkBox(context, model),
          onTap: () => model.openItem(item),
          minLeadingWidth: 0,
        ),
        const Divider(height: 1)
      ],
    );
  }

  Widget leading(BuildContext context, MainViewModel model) {
    return Container(
      height: double.infinity,
      child: Column(
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.center,
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          RoundCheckBox(
            size: 20,
            isChecked: item.selected,
            uncheckedColor: Colors.transparent,
            checkedColor: context.accentColorFaded,
            checkedWidget: const Padding(
              padding: EdgeInsets.all(4),
              child: Icon(Icons.check, size: 10),
            ),
            onTap: (_) => model.toggleSelection(item),
          ),
        ],
      ),
    );
  }

  Widget checkBox(BuildContext context, MainViewModel model) {
    return Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        Container(
          width: 50,
          height: 20,
          alignment: Alignment.center,
          decoration: const BoxDecoration(
              borderRadius: BorderRadius.all(Radius.circular(10)),
              color: Colors.red),
          child: AutoSizeText(
            '${item.dueCount}',
            minFontSize: 5,
            style: const TextStyle(color: Colors.white),
          ),
        ),
        const SizedBox(width: 15),
        PopupMenuButton(
          position: PopupMenuPosition.under,
          constraints: const BoxConstraints(),
          padding: EdgeInsets.zero,
          iconSize: 20,
          itemBuilder: (_) {
            return [
              PopupMenuItem(
                onTap: model.deselectAll,
                child: Text(context.str.deselectAll),
              )
            ];
          },
          child: Icon(Icons.more_vert_outlined, color: context.accentColor),
        ),
      ],
    );
  }

  Widget title(BuildContext context) => Text(
        item.name,
        style: Theme.of(context).textTheme.titleMedium!.copyWith(
            fontWeight: item is Folder ? FontWeight.bold : FontWeight.normal),
      );

  Widget? subtitle(BuildContext context) => item.description.isEmpty
      ? null
      : Text(
          item.description,
          style: Theme.of(context)
              .textTheme
              .titleSmall!
              .copyWith(fontWeight: FontWeight.w300),
        );
}

class ListReorder extends AutomaticAnimatedListReorderModel<DeckListItem> {
  final MainViewModel model;

  ListReorder(this.model, super.list);

  @override
  bool onReorderComplete(int index, int dropIndex, Object? slot) {
    list.insert(dropIndex, list.removeAt(index));
    final newList = list.indexed
        .map((pair) => pair.$2.cloneWithListOrder(pair.$1))
        .toList();
    model.saveList(newList);
    return true;
  }
}

image_2023-06-25_040702987

steveroseik commented 10 months ago

Did you find a solution for this problem. I'm facing the same issue and cannot find any way to change any colors

orlys-ag commented 7 months ago

There is a condition in AnimatedSliverChildBuilderDelegate that wraps the child like so:

if (addAnimatedElevation != 0.0 && reorderModel != null) {
  child = Material(
    elevation: data.dragging ? addAnimatedElevation : 0.0,
    child: child,
  );
}

The issue is that Material widgets have a default non-transparent color.

You have two solutions:

  1. You can extend AnimatedSliverChildBuilderDelegate if you want, and then add color: Colors.transparent to the Material widget.
  2. Set the addAnimatedElevation property to zero (.0), and then handle the elevation effect (shadow, etc.) yourself.