takataka430’s blog

.NET系を中心に勉強したことのまとめを書きます

LottieをXamarin.Formsで使ってみた

この記事はXamarin Advent Calendar 18日目の投稿です。

qiita.com

モバイルアプリでもいい感じのアニメーションを表示させたいと思い色々調べていたら、Lottieというライブラリを見つけました。
この記事ではアニメーションの作成から始めて、Lottieを使ってXamarin.Formsで使うまでの方法について書きたいと思います。

Lotitieとは

Adobe After Effectsを用いて簡単にアニメーションの作成ができるライブラリです。BodyMovinというライブラリを使い、JSONファイルとして書き出されたデータを読みこむことができます。

github.com

環境

PC

Mac Book Air

Xamarin関連

Visual Studio 2019 for Mac
Xamarin.Forms (4.4.0.991265)
Com.Airbnb.Xamarin.Forms.Lottie (3.0.3)

アニメーション関連

Adobe After Effects 2020

手順

1. アニメーション作成用ツールのインストール

AdobeAfter Effectsを利用します。有償ソフトですが、7日間の無料体験版もあります。

https://www.adobe.com/jp/products/aftereffects.html

After Effectsをインストールしたら、Bodymovinというプラグインを導入します。BodymovinはAfter Effectsで作成したアニメーションをJSON形式でエクスポートしてくれるツールです。
プラグインの追加は以下のページに記載があります。

https://github.com/airbnb/lottie-web#plugin-installation

2. アニメーションの作成

今回はAfter Effectsを使って、自分で作ったPNG形式の画像に簡単なアニメーションをつけてみました。以下の画像を上下左右ランダムに揺れるアニメーションをモバイルアプリ上で表示することを目標にします。

f:id:takataka430:20191217170313p:plain:w200

まず、After Effects のFile→Import→Fileから動かしたい画像を選択します。 (MacであればCommand + i でもいいです)
この時、Create Compositionにチェックを入れておきます。

f:id:takataka430:20191217170641p:plain

これを開くとCompositionというWindowが表示されていると思います。ここでアニメーションの設定を行います。

f:id:takataka430:20191217171223p:plain

今回は画像を揺らすアニメーションにするので、Wigglerという機能を使います。やり方は以下のサイトを参考にしました。

ウィグラー機能で、画面揺れを表現しよう! | AE Doctor

最後に作成したアニメーションをBodymovinを使ってエクスポートします。
メニューからWindow→Extensions→Bodymovinと選ぶと以下の画面になります。

f:id:takataka430:20191217174801p:plain

左のSelected にチェックを入れ、右側のDestination Folderにエクスポート先を指定し、Renderボタンを押します。これで保存先にjsonファイルとimagesというフォルダができていると思います。

以上でアニメーションの作成は完了です。

3. Xamarin.Formsへ実装

共有プロジェクト

まずはNugetからCom.Airbnb.Xamarin.Forms.Lottieをインストールします。 f:id:takataka430:20191218232420p:plain

XAMLファイルには以下のように記述します。

<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="LottieStudy.MainPage"
             xmlns:forms="clr-namespace:Lottie.Forms;assembly=Lottie.Forms">
    <StackLayout>
        <forms:AnimationView
            x:Name="AnimationView" 
            Animation="data.json"
            ImageAssetsFolder="images"
            AutoPlay="True" Loop="true"
            VerticalOptions="FillAndExpand"
            HorizontalOptions="FillAndExpand"/>
    </StackLayout>
</ContentPage>

ImageAssetsFolderには2でアニメーションをエクスポートしたときに作成したフォルダ名、AnimationにはJSONファイル名を入力します。

Android

共有プロジェクトと同様にNugetからCom.Airbnb.Xamarin.Forms.Lottieをインストールします。
MainAvtivity.csに以下のように追記します。

using System;
using Android.App;
using Android.Content.PM;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;

//ここを追加
using Lottie.Forms.Droid;

namespace LottieStudy.Droid
{
    [Activity(Label = "LottieStudy", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {
        protected override void OnCreate(Bundle savedInstanceState)
        {
            TabLayoutResource = Resource.Layout.Tabbar;
            ToolbarResource = Resource.Layout.Toolbar;

            base.OnCreate(savedInstanceState);

            Xamarin.Essentials.Platform.Init(this, savedInstanceState);
            global::Xamarin.Forms.Forms.Init(this, savedInstanceState);

            //ここを追加
            AnimationViewRenderer.Init();

            LoadApplication(new App());
        }
        public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
        {
            Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);

            base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }
}

2で作成したJSONファイルとフォルダをAssetsフォルダの中に保存します。 f:id:takataka430:20191218234603p:plain

動きは以下のようになります。

f:id:takataka430:20191218235704g:plain   
  

iOS側(調査中)

共有プロジェクトと同様にNugetからCom.Airbnb.Xamarin.Forms.Lottieをインストールします。

AppDelegate.csに追記します。

using System;
using System.Collections.Generic;
using System.Linq;

using Foundation;
using UIKit;

//追加
using Lottie.Forms.iOS.Renderers;

namespace LottieStudy.iOS
{
    [Register("AppDelegate")]
    public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
    {
        public override bool FinishedLaunching(UIApplication app, NSDictionary options)
        {
            global::Xamarin.Forms.Forms.Init();
            LoadApplication(new App());

            //追加
            AnimationViewRenderer.Init();

            return base.FinishedLaunching(app, options);
        }
    }
}

2で作成したJSONファイルとフォルダをAssetsフォルダの中に保存します。 f:id:takataka430:20191219000215p:plain

これで動くはずなんですが、Application Outputに以下のエラーが出てうまく表示されません・・・。 -[LOTLayerContainer _setImageForAsset:]: Warn: image not found: img_0.png
今後の課題にします。

以上、Xamarin.FormsでLottieを動かす方法でした。もっとAfterEffecctsを使いこなせるようになればいい感じのアニメーションが作れそうですね!