
Xamarin.Formsのアニメーション
既に実際のプロジェクトでXamarin.Formsを使用している場合は、おそらく組み込みのアニメーションメカニズムに出くわしたでしょう。 そうでない場合は、 「Xamarin.Formsを使用したアニメーションの作成」および「複合アニメーション」の記事を参照することをお勧めします。
ほとんどの場合、次のプロパティをアニメーション化する必要があります。
- スケール、要素スケール。
- 不透明度、透明度;
- 変換、レイアウトで取得された位置に相対的なx、yの追加オフセット。
- 回転、x、y、z軸の周りの回転。
Xamarin.Formsは低レベルのOSメカニズムを使用して、指定されたプロパティを設定します。これはパフォーマンスに大きな影響を与えます-オブジェクトの束全体を一度にアニメーション化しても問題はありません。 この例では、これらのプロパティに焦点を当てますが、必要に応じて、以下で説明するメカニズムを個別に拡張できます。
ステートマシン
ステートマシンを人間の言語で記述する場合、これはさまざまな安定状態(「読み込み中」または「エラー」など)になる可能性のあるオブジェクトです。 マシンは、外部イベントの影響下で状態を変更します。 州の数はもちろんです。 そのような機械の例は、エレベーターや信号機です。

何らかの理由で研究所で専門技術を勉強しなかった場合、または理論を勉強しなかった場合は、この記事を熟知することをお勧めします。
これはすべてアニメーションと関係があり、さらにXamarin.Formsと関係があるのでしょうか? 見てみましょう。
1つの画面、多くの状態、遷移アニメーションがあります
「Xamarin.Formsの画面状態の操作」の記事で、複雑なインターフェイスの開発を簡素化し、ビジネスアプリケーションのほとんどの画面に適したStateContainerコンポーネントについて既に説明しました。 このコンポーネントは、すべての状態が互いに独立して存在し、それらの間で単純な遷移「1つが消えた-2番目が現れた」で十分な場合にうまく機能します。

しかし、ある状態から別の状態への複雑でアニメーション化された遷移を実装する必要がある場合はどうでしょうか? 移動するには、スピンしてジャンプします。
例として、ほとんどのナビゲーターに実装されているように、住所を入力して地図を操作するための画面を見てみましょう。
次の1つの画面の状態間でアニメーション化された遷移があると想像してください。

ご覧のとおり、このような有限状態マシンを取得します。

状態から状態に移行するときは、次のアニメーションを実装する必要があります。
- FindAddressを入力するとき、アニメーションで古いコンテンツを非表示にし、新しいコンテンツをスムーズに表示する必要があります。 加えて、海賊行為のために、出現時にボタンをアニメーション化します。
- ShowRouteに切り替えるときは、古い状態を非表示にする必要があり、ルート情報を含む標識が画面の下部から消えます。
- ドライブに行くときは、古い状態を非表示にする必要があり、ルート情報を含む標識が一番上に表示されます。
- Mainに移動すると(最初の起動を除く)、現在の状態を非表示にしてボタンをスムーズに表示する必要があります。それにズームの小さなアニメーションも追加します。
私たちはあなたの機械を書きます
最も単純な実装を採用します。
- オートマトンには、初期化中に設定される状態の固定セットがあります。
- 各状態は、UI要素に必要な一連のアニメーション(プロパティの最終値)によって記述されます。
- 新しい状態に入ると、オートマトンの初期化中に追加された配列のすべてのアニメーションが並行して起動されます。
遷移の履歴は保存しませんが、マシンがどのユーザーイベントに対してある状態から別の状態に移動したかは重要ではありません。 アニメーションを伴う新しい状態への移行のみがあります。
したがって、Storyboardと呼ばれる最も単純なマシンは次のようになります。
public enum AnimationType { Scale, Opacity, TranslationX, TranslationY, Rotation } public class Storyboard { readonly Dictionary<string, ViewTransition[]> _stateTransitions = new Dictionary<string, ViewTransition[]>(); public void Add(object state, ViewTransition[] viewTransitions) { var stateStr = state?.ToString().ToUpperInvariant(); _stateTransitions.Add(stateStr, viewTransitions); } public void Go(object newState, bool withAnimation = true) { var newStateStr = newState?.ToString().ToUpperInvariant(); // Get all ViewTransitions var viewTransitions = _stateTransitions[newStateStr]; // Get transition tasks var tasks = viewTransitions.Select(viewTransition => viewTransition.GetTransition(withAnimation)); // Run all transition tasks Task.WhenAll(tasks); } } public class ViewTransition { // Skipped. See complete sample in repository below public async Task GetTransition(bool withAnimation) { VisualElement targetElement; if( !_targetElementReference.TryGetTarget(out targetElement) ) throw new ObjectDisposedException("Target VisualElement was disposed"); if( _delay > 0 ) await Task.Delay(_delay); withAnimation &= _length > 0; switch ( _animationType ) { case AnimationType.Scale: if( withAnimation ) await targetElement.ScaleTo(_endValue, _length, _easing); else targetElement.Scale = _endValue; break; // See complete sample in repository below default: throw new ArgumentOutOfRangeException(); } } }
上記の例では、入力チェックは省略されており、完全版はリポジトリにあります(記事の最後にあるリンク)。
ご覧のとおり、新しい状態への移行中に、必要なプロパティのスムーズな変更が並行して行われます。 アニメーションなしで新しい状態に移行する機会もあります。
ステートマシンを使用します
したがって、マシンがあり、それを接続して要素の必要な状態を設定できます。 新しい状態を追加する例:
_storyboard.Add(States.Drive, new[] { new ViewTransition(ShowRouteView, AnimationType.TranslationY, 200), new ViewTransition(ShowRouteView, AnimationType.Opacity, 0, 0, delay: 250), new ViewTransition(DriveView, AnimationType.TranslationY, 0, 300, delay: 250), // Active and visible new ViewTransition(DriveView, AnimationType.Opacity, 1, 0) // Active and visible });
ご覧のとおり、ドライブの状態については、個々のアニメーションの配列を設定します。 ShowRouteViewとDriveViewは、XAMLで定義されている通常のビューです。以下に例を示します。
しかし、新しい状態に移行するには、単にGo()メソッドを呼び出すだけで十分です。
_storyboard.Go(States.ShowRoute);
コードは比較的小さく、グループアニメーションは実際には単に数字のセットで作成されます。 有限状態マシンは、ページだけでなく、個々のビューでも機能し、アプリケーションを拡張します。 ストーリーボードをビジネスロジックと混合せずに、ページ(ページ)コード内でストーリーボードを使用する方が適切です。
また、ユーザーインターフェイスのすべての要素を説明するXAMLの例を示します。

アニメーションを使用して要素の色を変更する機能を追加する場合は、記事「Xamarin.Formsでのカスタムアニメーションの構築」で説明されている実装に慣れることをお勧めします。
リポジトリの記事から完全なプロジェクトコードを見つけることができます。
https://bitbucket.org/binwell/statemachine
そしていつものように、コメント欄で質問してください。 接続へ!
著者について
著者の他の記事:
- ステートマシン、アニメーション、およびXamarin.Formsの共通点は何ですか?
- モバイルアプリケーションのテストに最適な7つのデバイスファーム
- 自動化されていない、または実際のプロジェクトのXamarinについて自動化する
- XamarinアプリケーションのOAuth認証
- Microsoft devopsパイプラインを使用したモバイルソフトウェアの展開
- 人の役目を果たすDevOps
- Xamarinアプリケーション用の便利なREST
- Microsoft AzureとXamarin.Formsに基づいたMVP(最小限の実行可能な製品)の迅速な作成
- Xamarin.Formsのクッキング:環境のセットアップと最初のステップ
- Xamarin.Formsパフォーマンスの改善
- Xamarin.Formsで画面状態を操作する
- Xamarin.Forms用のFacebook SDKの接続
- Xamarin.FormsのVK SDKを接続します