jonataslaw / getx

Open screens/snackbars/dialogs/bottomSheets without context, manage states and inject dependencies easily with Get.
MIT License
10.26k stars 1.61k forks source link

How to animate a listview with GetBuilder #513

Closed facuparedes closed 4 years ago

facuparedes commented 4 years ago

Hi! I'm using Getx and I love it. However I need help, I spend a lot of time trying to animate ListView.builder's items when I call update() from my controller. I tried to use AnimatedList but it gets laggy when list becomes larger. Also I tried using "Transition"'s widget like SlideTransition, but it doesn't work because GetBuilder rebuilds the widget. Please, can anybody help me? How can I do that?

Greetings!

Nipodemos commented 4 years ago

hello! could you post here how you try to use the slideTransition? To be honest i tried to reproduce this case, and i noticed that i don't know how to do it 😅 (at least not without animatedList)

Have you tried to use the reactive state manager? It has the advantage of only rebuild the exactly widget you need to be rebuilded

facuparedes commented 4 years ago

hello! could you post here how you try to use the slideTransition? To be honest i tried to reproduce this case, and i noticed that i don't know how to do it 😅 (at least not without animatedList)

Have you tried to use the reactive state manager? It has the advantage of only rebuild the exactly widget you need to be rebuilded

Firstly, thanks u for your answering! I tried to replace GetBuilder with Obx, but my ListView.builder is rebuilt by Obx when my List is updated, so it also doesn't work. To use SlideTransition, I wrote a AnimationController in a GetxController's class, just like this:

Messages.controller.dart

class MessagesController extends GetxController {
  static MessagesController get find => Get.find();

  AnimationController listAnimationController;
  List<Message> messageList;

  @override
  void onInit() {
    this.listAnimationController = AnimationController(vsync: NavigatorState(), duration: Duration(milliseconds: 500));
  }
}

Then, in my StatelessWidget's build constructor:

messagesList.dart

class MessagesList extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return GetBuilder<MessagesController>(
      init: Get.put(MessagesController()),
      initState: (_) => MessagesController.find.getMessages(),
      didUpdateWidget: (_, __) => MessagesController.find.listAnimationController.forward(),
      builder: (c) {
        if (c?.messageList == null) {
          return Center(child: CustomCircularProgressIndicator());
        } else {
          return ListView.builder(
            reverse: true,
            itemCount: c.messageList.length,
            itemBuilder: (_, index) {
              return SlideTransition(
                position: Tween<Offset>(begin: Offset(0, 1), end: Offset.zero).animate(MessagesController.find.listAnimationController),
                child: ListTile(
                  title: Text(c.messageList[index].text),
                ),
              );
            }
          );
        }
      },
    );
  }
}

However, animation is not played. Do you know another way to do that? I can't use AnimatedList, because that widget doesn't works like Listview.builder, which only load widgets that are in the viewport on memory.

Nipodemos commented 4 years ago

hey man, sorry to say that but i don't know how to solve your issue. Tried to paste your code and change to Obx but got weird error of addListener was called on null, but i am almost sure that it's my mistake

the only thing i can think is: Instead of one Obx for your listView.builder, you should use a Obx for each item, that way they are updated separately

facuparedes commented 4 years ago

hey man, sorry to say that but i don't know how to solve your issue. Tried to paste your code and change to Obx but got weird error of addListener was called on null, but i am almost sure that it's my mistake

the only thing i can think is: Instead of one Obx for your listView.builder, you should use a Obx for each item, that way they are updated separately

Hey, thanks u for your reply! If I use Obx for each item, how can I update listview.builder? Because itemCount parameter needs to be updated to insert a new item

facuparedes commented 4 years ago

Sorry to bother you @jonataslaw, but may be do you know how can we do it? It would be great your reply!

Nipodemos commented 4 years ago

Unfortunaly you will need to dig up by yourself. Since this is not an issue, and is not resolvable, i'm closing

LiJoeAllen commented 1 year ago

To achieve the desired effect, you can update the key of the AnimatedList.