mauiandroid-animationlottieskiasharp

Lottie animation (using SkiaSharp) does not display inside collectionview.empyview content view


I have a custom filter control that checks if the entered data matches with something stored inside a dictionary. If something matches, the item source of the collection view is populated with these data (saved in an observable collection). If nothing matches, the collection view will be empty, so I have defined the emptyview property of the collection view as such:

<CollectionView.EmptyView>
   <ContentView MinimumHeightRequest="485" IsVisible="{Binding IsEmpty}">
      <VerticalStackLayout HorizontalOptions="CenterAndExpand" VerticalOptions="StartAndExpand"
                           Spacing="30"
                           Margin="0, 0, 0, 0">
         <Grid HorizontalOptions="CenterAndExpand" VerticalOptions="StartAndExpand">
            <lottie:SKLottieView Source="earthanimation.json"
                                 RepeatCount="-1"
                                 HeightRequest="350"
                                 WidthRequest="350"
                                 HorizontalOptions="CenterAndExpand"
                                 VerticalOptions="CenterAndExpand"/>
            <Label Text="NOT FOUND" TextColor="LightBlue"
                   FontFamily="FAR" FontSize="30" FontAttributes="Bold"
                   VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand"/>
         </Grid>

         <Label Text="Location not found"
                FontSize="15" FontFamily="Conthrax"
                HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"/>
      </VerticalStackLayout>
   </ContentView>
</CollectionView.EmptyView>

Notice that I bound the IsVisible property, this because when the filter entry was tapped, something triggered and the emptyview was showing, even though I didn't search for nothing. So I made it visible only when the actual search process returns 0 matches.

Everything is working fine except for the Lottie animation; it's not displaying whatsoever. The only way to make it work, in debug, is to remove the Lottie control, then once the UI refreshes, paste it back and it works.

I have no idea on how to resolve this.


Solution

  • I found a workaround, which is to remove Lottie first and add it again in code behind. Please consider the following code:

    For the XAML which consumes the Lottie animation.

    Please note that we should also add the Lottie animation in the XAML, otherwise it will not show.

    <Button
       x:Name="CounterBtn"
       Text="Click me"
       SemanticProperties.Hint="Counts the number of times you click"
       Command="{Binding ClickedCommand}"
       HorizontalOptions="Center" />
    
    ....
    
    <CollectionView.EmptyView>
       <ContentView MinimumHeightRequest="485" IsVisible="{Binding IsEmpty}">
          <VerticalStackLayout x:Name="mystack" HorizontalOptions="CenterAndExpand" VerticalOptions="StartAndExpand"
                               Spacing="30"
                               Margin="0, 0, 0, 0">
             <Grid x:Name="mygrid" HorizontalOptions="CenterAndExpand" VerticalOptions="StartAndExpand" HeightRequest="350"
                                     WidthRequest="350">
    
               <skia:SKLottieView  x:Name="mylot" Source="dotnetbot.json"
                                       RepeatCount="-1"
                                       HeightRequest="350"
                                       WidthRequest="350"
                                       HorizontalOptions="CenterAndExpand"
                                       VerticalOptions="CenterAndExpand"/>
               <Label Text="NOT FOUND" TextColor="Black"
                   FontFamily="FAR" FontSize="30" FontAttributes="Bold"
                   VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand"/>
    
             </Grid>
    
             <Label Text="{Binding MyText}"
                    FontSize="15" FontFamily="Conthrax"
                    HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"/>
          </VerticalStackLayout>
       </ContentView>
    

    For ViewModel, let's implement ClickedCommand. Please Note that I use MessagingCenter here. Because when no item in collection we want to send a message to code behind to add the lottie again

        public Command ClickedCommand
        {
            get
            {
                return new Command(() =>
                {
                    ItemCollection.RemoveAt(0);
                    if(ItemCollection.Count ==0)
                    {
                        MessagingCenter.Send<MainPageViewModel>(this, "Hi");
                    }
    
                });
    
            }
        }
    

    In .NET 7, it is recommended to use WeakReferenceMessenger instead of MessagingCenter. The usages are similar.

    For code behind, we just subscribe the message and we remove and add lottie again.

    public MainPage()
    {
        InitializeComponent();
        this.BindingContext = viewModel = new MainPageViewModel();
        MessagingCenter.Subscribe<MainPageViewModel>(this, "Hi", (s) =>
        {
            mygrid.Clear();
            SKLottieView myanimatedview = new SKLottieView();
            var a = new SKFileLottieImageSource();
            a.File = "dotnetbot.json";
            myanimatedview.WidthRequest = 300;
            myanimatedview.HeightRequest = 300;
            myanimatedview.Source = a;
            myanimatedview.RepeatCount = -1;
            mygrid.Add(myanimatedview);
            Label label = new Label()
            {
                Text = "NOT FOUND",
                TextColor = Colors.LightBlue,
                VerticalOptions = LayoutOptions.CenterAndExpand,
                HorizontalOptions = LayoutOptions.CenterAndExpand
            };
            mygrid.Add(label);
        });
    
    
    }
    

    For more info, you could refer to SKLottieView. You could also report an issue on GitHub: SKLottie Issues on GitHub

    enter image description here