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を使いこなせるようになればいい感じのアニメーションが作れそうですね!

【C# Tokyo で発表してきました】Dependency Injection はじめの一歩

10月24日に開催された「.NET Core 3.0 リリース記念 C# Tokyo 2019/10」で発表してきました。

csharp-tokyo.connpass.com

発表スライドはこちらです。

今回テーマを Dependency Injectionに選んだのは、自分がちょうど調べていたことと、.NET Coreにも関連することなので、ちょっと背伸びになるけれど挑戦してみようと思ったためです。ただ、いざ発表用の資料を作ると難しいですね・・・。もっと勉強が必要だと思いました。この発表が少しでも聞いている人のお役に立てたなら嬉しいです。

Remote Assistのモバイルアプリを使ってみた

今月の初めにDynamics 365 Remote Assistのアップデートでモバイルアプリが一般提供されましたね。

cloudblogs.microsoft.com

というわけで早速使ってみました。

Remote Assist とは

その前に、まずはRemote Assistについて説明します。
簡単にいうとTV会議に加えて、矢印や線を画面で共有することによって遠隔地にいる相手とコミュニケーションをとることが出来るツールです。
文字だけだとわかりにくいと思うので以下のリンクの「概要を見る」をクリックしてビデオを見てください。イメージしやすいと思います。

dynamics.microsoft.com

公式ドキュメントはこちら

docs.microsoft.com

Remote Assist モバイルアプリを使ってみた

利用するためにはライセンスが必要なのですが、ちょっと試すだけだったらアプリをダウンロードするだけで試すことができます。通信はできませんが、空間に矢印を置いたり線を引いたりを体験することができます。

手順としては、まずスマートフォンにアプリをダウンロードします。

Android : https://play.google.com/store/apps/details?id=com.microsoft.ramobile
iOS : https://apps.apple.com/app/id1470512565

これで準備はOKです。
アプリを起動して、試すボタンを押します。

f:id:takataka430:20191015004717p:plain:w200

以下の画像のようにカメラ越しに見ている風景に矢印を立てたり線を描いたりすることができます。

f:id:takataka430:20191015004535p:plain:w200

簡単に出来るので是非使ってみてください。

【Xamarin.Forms】TabbedPageクイックスタート

Xamarin.Formsでタブページの使い方を調べていたのですが、最初よくわからなくてつまづきました。簡単に使い始めるための方法を書きます。 ちなみに、プロジェクトを作成する際に「タブ付きフォームアプリ」をテンプレートとして選択すれば最初から使えるわけですが、今回は「空白のフォームアプリ」を選択した場合の方法を記載します。

環境

Visual Studio 2019 for Mac
Xamarin.Forms 4.1.0.555618

やり方

前提として、「空白のフォームアプリ」で新しいアプリを作成している状態を想定します。

まずは.NetStandardのプロジェクトを右クリックし、「追加」→「新しいファイルを作成」を選択します。

f:id:takataka430:20190907005526p:plain

左メニューからFormsを選択し、その中の「フォーム ContenPage XAML」を選択、名前をつけて右下の新規をクリックします。

f:id:takataka430:20190907005543p:plain

これでContentPageが2つできました(元からあったものと、新規追加したもの)。この2つをタブページによって表示の切り替えを行います。

先ほどと同様に.NetStandardのプロジェクトを右クリックし、「追加」→「新しいファイルを作成」を選択します。 左メニューからFormsを選択し、その中の「TabbedPage XAMLの追加」を選択、名前をつけて右下の新規をクリックします。

f:id:takataka430:20190907010017p:plain

作成したタブページにコードを追記して行きましょう。

<?xml version="1.0" encoding="utf-8" ?>
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
            xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
            x:Class="XF_TabbedPage.MyTabbedPage"
            xmlns:local="clr-namespace:XF_TabbedPage;assembly=XF_TabbedPage">
    <local:MainPage Title="FirstPage"/>
    <local:SecondPage Title="SecondPage"/>
</TabbedPage>

xmlns:local="clr-namespace:XF_TabbedPage;assembly=XF_TabbedPage"名前空間アセンブリを指定しています。
local:MainPage local:SecondPageそれぞれでタブページで表示したいページを指定しています。Titleでタブページの表示名を設定します。
MainPage SecondPageは上で作成したContentPageの名前です。)

f:id:takataka430:20191012151655g:plain

このようにタブページによってページを切り替えることができます。モバイルアプリらしくなりましたね。
是非使ってみてください。

参考:

Xamarin.Forms のタブ付きページ - Xamarin | Microsoft Docs

iOSDCに参加してきました

2019/9/5 - 9/7に開催された iOSDC2019 に参加してきました。

iosdc.jp

興味深いセッションがたくさんあってとても楽しかったです。ブログを書くまでがiOSDCなので、セッションの感想を書いていこうと思います。

普通に書くと即メモリーリーク!こんなに大変だけど、俺は Xamarin.iOS を使い続けるぜ!

www.slideshare.net Xamarin.iOSの仕組みの解説でした。Objective-Cが辛くて、楽をするためにXamarin.iOSを始めたけど、どちらにしてもObjective-Cの知識が必要なので、結局は覚えることが増えただけだったそうです・・・。ただ、Azureとの連携がやりやすいなど、扱えるようになればとても便利なので今後も楽しく使っていくとのこと。素晴らしい!

Heart of Swift(資料未公開)

Swiftは「Value Semantics」と「Protocol-Oriented Programming」という二つの概念が根幹をなしているそうです。知らなかった・・・。コレクションについてはC#だと参照型でSwiftだと値型でこれが強みになるそうです。なぜ強みになるのか、自分なりに調べてみようと思います。

iPhoneのカメラで写真撮影から現像までの技術を紐解く

iPhoneカメラのお話。カメラの歴史やレンズの話から始まり、iPhoneカメラで撮影・現像ができるアプリを作ろうという内容でした。私は普段、ソフトウェアについて勉強することが多いので、ハードウェアのお話は興味深かったです。最近はARの技術も発達してきているので、こういったことを知っておくとアプリ開発の際に役立つのではないかと思います。

すべての人のためのアクセシビリティ対応

アクセシビリティとはあらゆる人がどのような環境でもサービスにアクセスできように考慮することであり、特定の人のためのものではないそうです。例えばネットワーク環境が悪い、料理中にスマホを触れないという状況などです。iOSにはたくさんのアクセシビリティの機能があるので、少しづつアプリに追加していこうという内容でした。 アクセシビリティについても少しづつ理解を深めていこうと思います。

まとめ

様々なセッションが聞けてとても刺激になりました。できれば次回は私も発表したいなと思いました。

「JXUGC #25 最新情報アップデート&LT 大会」でLT発表してきました

8月31日に行われた「JXUGC #25 最新情報アップデート&LT 大会」にて、LTで発表を行いました。

jxug.connpass.com

今回のJXUGは昨年の12月以来の久しぶりの参加でした。せっかくなので何か発表したいと思い、LTに応募しました。
発表内容は以下の通りです。

なぜこのテーマにしたかというと、Xamarinを勉強し始めてから長い間「アプリ作りたい。でもネタがない。」という状態だったのですが、一応アプリを作れたので、こんなの作った!と発表したかったからです。シンプルなアプリなのですが、思いの外苦労することも多かったのでその知見を共有するという目的もありました。

思えば一年前のJXUG(初心者歓迎XamarinのLT会!Xamarin入門者の集い #4)でLTをした時に、「オリジナルアプリを作ることが今後の目標」と言いました。今回の発表でその目標は達成できたのかーと思います。

今後も勉強続けてネタを見つけて発表したいと思います。聞いていただいた皆さん、ありがとうございました。

Write Code Every Dayを始めてみた

「Write Code Every Day」とは文字通り毎日コードを書こうという試みです。

【参考】 Write Code Every Day - Speaker Deck

自分もやってみたいと思ったので始めてみました。 なぜ始めたかというと、プライベートでもコードを書く習慣を身に付けたいと思ったからです。

しかし、私は毎日何かをやるのが苦手な人です。そこで自分流のルールを考えてみました。意識したのは、完全に止めてしまわないように、とにかくハードルを下げることです。

その1:意味のないコードでもOKとする

例えばコメントで何か書くとか、不要なコードを削るとか、そういうのでもOKとしました。その方が毎日気軽な気持ちでやる気になれます。

その2:続かなくてもあまり気にしない

仮に忙しかったり寝てしまったりしてその日にコードを書けなかったとしても「しょうがない、次から頑張ろう」とすぐに切り替えるようにしています。変に気にしても落ち込んでしまうので・・・

その3:進捗を見てうっとりする

これが一番重要かもしれません。「おお、できてるじゃん!!」と自分の進捗を見ることで次の日もやろうと思えます。

効果は?

毎日コードを書く、というのは残念ながらまだできていません。しかし、始める前に比べると家でコードを書く頻度は明らかに増えました。

実際の進捗

以下のような感じです。(始めたのは今年の7月です)

f:id:takataka430:20190819224258p:plain

書いてない日も結構多いですが・・・始める前に比べて明らかに頻度が増えていますね。 今後は毎日書いてプッシュするようになりたいです。

というわけで、こんな感じでコツコツ続けていきたいと思います。