DEV Community

Ashutosh Dubey
Ashutosh Dubey

Posted on • Edited on

List animation in Ionic 6 & Angular

In this article we're gonna learn how to create list animations in Ionic.

We're gonna implement this animation

List animation ionic gif

Create Grid List

First we need to implement a Grid List of 2 columns, that we can implement using below code

home.page.html

<ion-content>
  <ion-grid>
    <ion-row>
      <ion-col
        size="6"
        *ngFor="let temp of templates;"
      >
        <ion-item
          class="ion-no-padding"
          lines="none"
        >
          <ion-img [src]="temp.background"> </ion-img>
        </ion-item>
      </ion-col>
    </ion-row>
  </ion-grid>
</ion-content>
Enter fullscreen mode Exit fullscreen mode

It's a simple code, here size="6" gives every item half of screen width, as explained in ion-grid documentation

It (grid) is based on a 12 column layout with different breakpoints based on the screen size

And templates here is list array we have defined in home.page.ts

export class HomePage implements AfterViewInit {
  // You can give your own background asset path here
  templates = [
    {
      id: 0,
      background: 'assets/hotel/hotel_booking.png',
      screenPath: 'hotel-booking',
    },
    {
      id: 1,
      background: 'assets/fitness_app/fitness_app.png',
      screenPath: 'fitness-app',
    },
    {
      id: 2,
      background: 'assets/design_course/design_course.png',
      screenPath: 'design-course',
    },
  ];

  constructor() {}
}
Enter fullscreen mode Exit fullscreen mode

Implement the Animation

Now we need to implement the animation, for that we need reference for list items

  • First assign id to ion-col which will contain reference for all child items

home.page.html

<ion-content>
  <ion-grid>
    <ion-row>
      <ion-col
        size="6"
        *ngFor="let temp of templates;"
        #templateList   <- Add this
      >
        // same as above
      </ion-col>
    </ion-row>
  </ion-grid>
</ion-content>
Enter fullscreen mode Exit fullscreen mode
  • Now in home.page.ts we're gonna use ViewChildren as we need reference for every list item to animate
export class HomePage implements AfterViewInit {
  // Here 'templateList' is the id
  @ViewChildren('templateList', { read: ElementRef })
  templateListRef: QueryList<ElementRef>;

  ...
}
Enter fullscreen mode Exit fullscreen mode
  • Now next step is to animate list items using reference variable templateListRef we created in last step
import { AnimationController } from '@ionic/angular';

export class HomePage implements AfterViewInit {
  @ViewChildren('templateList', { read: ElementRef })
  templateListRef: QueryList<ElementRef>;

  constructor(private animationCtrl: AnimationController) {}

  ngAfterViewInit() {
    this.initListAnimation();
  }

  initListAnimation() {
    const itemRefArray = this.templateListRef.toArray();
    for (let i = 0; i < itemRefArray.length; i++) {
      const element = itemRefArray[i].nativeElement;

      this.animationCtrl
        .create()
        .addElement(element)
        .duration(1000)
        .delay(i * (1000 / 3))
        .easing('cubic-bezier(0.4, 0.0, 0.2, 1.0)')
        .fromTo('transform', 'translateY(50px)', 'translateY(0px)')
        .fromTo('opacity', '0', '1')
        .play();
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Here as we need to wait for screen to first initialise only then we can get reference for any view, we will run our animation in ngAfterViewInit.
In initListAnimation function we're iterating over templateListRef as we need to animate every item in the list
You can read the Ionic Animation documentation here to get an idea how animations works in ionic.

  1. First we need to import AnimationController through which we can animate any element, then defined it in constructor.
  2. addElement(element):- Add element that we're animating, here element is list item.
  3. duration(1000):- animation will run in 1000ms (1 second) duration.
  4. delay(i * (1000 / 3)):- Animation for subsequent items will be delayed so that all items don't animate at the same time but one after the other.
  5. easing:- Easing effect for animation, visit here for better understanding.
  6. fromTo basically animate a element's properly from start to end position. Like here as you can see in the gif above items are translating vertically and slowly fading in, so here we are animating transform from initial 50px below to 0px and opacity from 0 to 1.
  7. play:- Play the animation with all specified properties.

And it's done, the list animation should work as expected.

Flicker issue with android

Don't know about you but for me on android the list was flickering a little as shown in gif below

List flicker android issue

Now if you search for this issue on google you'll most probably find suggestion to use trackBy as here and here where we give every list item a unique id, but for some reason it didn't fix it for me.
So I had to come up with below workaround.
Here we wait for 500ms for page to initialise properly, the run the animation.

home.page.ts

export class HomePage implements AfterViewInit {
  constructor(
    private animationCtrl: AnimationController,
    private platform: Platform // <- add this
  ) {}

  ngAfterViewInit() {
    // move 'initListAnimation' function inside timeout
    // As I faced this issue only on Android, we won't wait in case of iOS
    setTimeout(
      () => this.initListAnimation(),
      this.platform.is('android') ? 500 : 0
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

In home.page.html we'll give initial opacity: 0 as list items shouldn't show to user while we're waiting (500ms)

<ion-content>
  <ion-grid>
    <ion-row>
      <ion-col
        style="opacity: 0"   <- Add this
        size="6"
        *ngFor="let temp of templates;"
        #templateList
      >
        // same as above
      </ion-col>
    </ion-row>
  </ion-grid>
</ion-content>
Enter fullscreen mode Exit fullscreen mode

This should fix the issue.
Do suggest if there's a better solution.

Conclusion

Following the above steps animation should work as expected.
This article is part of my open source project Ionic-UI-Templates, so do check that out for complete code. In this project I'm using Ionic 6 with Angular and Capacitor as runtime environment.

Repo link:- Ionic-UI-Templates

Video:-

Note:- This is my first ever article in any platform, so I would really appreciate for any suggestions to improve the article. Also there could be lot of grammatical mistakes so try to ignore them or do provide correction in the comments below, Thanks.

Top comments (0)