In this article we're gonna learn how to create list animations in Ionic.
We're gonna implement this animation
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>
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() {}
}
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>
- 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>;
...
}
- 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();
}
}
}
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.
- First we need to import
AnimationController
through which we can animate any element, then defined it in constructor. -
addElement(element)
:- Add element that we're animating, here element is list item. -
duration(1000)
:- animation will run in 1000ms (1 second) duration. -
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. -
easing
:- Easing effect for animation, visit here for better understanding. -
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 animatingtransform
from initial 50px below to 0px andopacity
from 0 to 1. -
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
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
);
}
}
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>
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)