Yandexレクチャー:高度なUI、パート2

これは、モバイルYandex.Mailチームの開発者であるDmitry Svirikhinによる講義の第2部です。

-引き続きAndroid開発者の典型的な問題とその解決方法を検討します。 アプリケーションでのUIの不整合の問題、キーボードとの対話時に発生する可能性のある問題、状態を失う問題の解決方法、およびカスタムビューを効果的に適用する方法については既に検討しました。 2番目の部分全体を別の問題に充てます。これは「対話性の欠如」と呼ばれます。 アプリケーションをユーザーにとってよりインタラクティブで理解しやすいものにする方法を見てみましょう。


最初に、双方向性の欠如の例を挙げます。 私が今お伝えしている報告書の主要なポイントとともに付録に戻ります。 ここで、ユーザーがそれを開き、2番目の部分をタップすると、ユーザーにはまったく理解できない何かが起こります。



もう一度見てみましょう。 第二の部分をタップすると、突然、何かが起こりました。 ユーザーは、今何が起こっているのかを理解し、理解するためにある程度の時間を必要とします。 したがって、この方法で、アニメーションを使用してこのユーザーにアクションの望ましい順序を伝えることができます。

ああ、2番目の部分が明らかになり、最初の部分が上がっています。 同時に、ユーザーは、上にスクロールすると再び最初の部分に戻ることを理解します。このようなアニメーションのために、ユーザーにとってこれは明白になります。

既にご想像のとおり、アニメーション、2017年にアニメーションを作成する方法、実際に使用できるもの、使用すべきものについて説明します。

一般的に、2017年に動くものを作成する方法はたくさんあります。 以下にリストを示します。 そして、あなたはすでにあなたの講義でそれらのいくつかに部分的に触れているかもしれません。 しかし、今、私たちはそれらのそれぞれに深く没頭し、どれが本当に必要なのかを理解します。

アニメーションの表示から始めます。 これは、バージョン2.3でAndroidを使用する前のビューをアニメーション化する主な方法です。 そして2009年から2010年には、何かが回転しているだけなら、誰もアニメーションについて全く考えていませんでした。 したがって、Viewアニメーションには、アニメーションを使用して行うことができるこれらの変更の絶対的に小さなセットがあります。 ただし、大きなマイナス点が1つあります。これは、レンダリング段階でビュービューを変更するだけです。 つまり、たとえば画面から飛び出すような種類のボタンを作成した場合、アニメーション中にボタンが元々あった場所をクリックすると、このボタンのクリックとして計算されます。 したがって、このアニメーションの方法は時代遅れであると言うことができ、2017年にそれを使用する価値はありません。したがって、詳細に検討せず、すぐに次の方法に進みます。


描画可能なアニメーションは、それを理解するためにアニメーションを作成する方法であり、最も簡単な方法は、それを表すXMLを調べることです。 実際、これは通常のフレームごとのアニメーションであり、それ以上のものではありません。 また、他の方法では実行できない非常に複雑な場合にのみ使用する必要があります。 このアニメーションは、システムごとに非常に複雑です。なぜなら、おそらく各フレームに対しても、新しいドロウアブルをロードする必要があるからです。 したがって、極端な場合にのみ使用する価値もあります。

そして、最も興味深いものであるValueAnimatorに進みます。これは、Androidの3番目のバージョンに登場しました。 これは基本的なアニメーションエンジンです。 そのプラスは、絶対にビューに添付されないことです。 ValueAnimatorには、フレーム形成のプロセスで独自の呼び出し階層があります。 そして、ValueAnimatorで何かをアニメーション化するには何が必要ですか? 初期値、最終値、リスナーを示す値を指定する必要があります。リスナーでは、中間値が取得され、ビューのいくつかでそれらを使用できます。

一般的に、クライアント開発では、ValueAnimatorはあまり使用されませんが、それを使用するためにどのコードを記述する必要があるかはまだわかります。

あなたが想像することができる最もシンプルで退屈なアニメーションを見ていきます-これはクロスフェードです。 それはシンプルで退屈ですが、それにもかかわらず、画面を変更するときにいくつかのコーナーを滑らかにする必要がある場合、必要なときにうまく機能します。


このクロスフェードが機能するように、ValueAnimatorから必要なコードをすぐに見てみましょう。 値を0から1および1から0にアニメートするには、それぞれ2つのValueAnimatorsを作成する必要があります。 次に、それぞれにUpdateListenerを設定します。アニメーターから現在のアニメーション値を取得し、setAlphaメソッドを使用してビューに直接移動します。 また、AnimatorSetも必要です。これは、順次または並行して実行できる多くのアニメーターを定義します。 これを自分で決定します。 私たちの場合、彼らが言うように、playTogetherメソッドは同時に実行されます。


また、このアニメーションの長さ、および呼び出すリスナー、アニメーションの開始前と終了後に呼び出すメソッドを設定します。 したがって、アニメーションを開始する前に、必要なビューを表示します。 アニメーションが終了すると、ビューが非表示になり、それに応じて表示が消えます。

次に、ValueAnimator.ofintを使用して0から255までの整数をアニメーション化する例を使用して、アニメーターエンジンの一般的な動作を見てみましょう。

Animatorの時間は0〜1の実数値として表されます。つまり、Androidのフレームが16ミリ秒と2/3ミリ秒で描画されることを考慮すると、167ミリ秒のアニメーションがあるとします。 10フレームで実行する必要があります。 つまり、合計時間の1/10は、エンジンに表示されるとおり、各フレームに対してです。

4番目のフレームのアニメーション計算がどのように見えるか、つまり、アニメーター時間が0.4の場合を見てみましょう。

最初に、0.4の値がTimeInterpolatorに分類されます。これは、アニメーションの発生速度を決定する関数です。 たとえば、アニメーションの速度を上げたい場合は、例としてAccelerateInterpolatorを使用できます。 通常の2次関数の増加関数を決定します。また、TimeInterpolatorが入力で0から1の値を受け取り、それに応じてそれを返す必要があることも注目に値します。

したがって、この場合のTimeInterpolatorは値0.16を返します。これは補間時間と呼ばれ、既にTypeEvaluatorに供給されています。 TypeEvaluatorは、時間に対してアニメーション中にオブジェクトがどのように変化するかを決定します。 つまり、たとえば、単純なintをアニメートする場合、すべてがここで非常に簡単に計算されます。最終値を取得し、そこから初期値を減算し、時間を掛けます。 この例では、0.16です。 結果の値40がAnimatorに返され、Animatorに設定された後、このAnimatorがUpdateListenerにスローされます。 必要なものすべて-アニメーション化された値-を取得し、何らかのビューを適用できます。 これは、サンプルコードで行われました。

ここで最も重要なことは、TimeInterpolatorとTypeEvaluatorを置き換えて、それぞれの場合に必要な方法を正確に実行できることを理解することです。

まず、システム内のTimeInterpolatorsを見てみましょう。

まず、最も古典的なものを検討してください。 主にそして最も頻繁に使用される3つはここにあります-これは加速する機能を定義するAccelerateInterpolatorです。 原則として、画面から消える要素に使用する必要があります。 黄色のボールを見ると、画面から飛び出します。

なぜ速度が向上する機能があるのですか? そのため、ほとんどの場合、この要素は単純に画面に費やされ、ユーザーは正確に気付きました。 たとえば、欠落している要素に対してDecelerateInterpolatorを使用した場合、逆に速度を上げると、ユーザーはこれに気付かないことさえあります。

したがって、画面に表示される要素にはDecelerateInterpolator(青いボール)を使用する必要があります。 また、AccelerateDecelerateInterpolatorは、速度が最初に増加し、それに応じて減少する関数を定義します。 ビューに関連付けられているアニメーションに使用する必要があります。これは、画面上で単に変化し、サイズまたは位置を変更し、画面上に残ります。

また、Android 5には、既に検討したものとまったく同じような最新の補間器があります。 彼らはよりスムーズかつ自然に動作すると考えられています。 確かに、それらは少し見栄えがよく、ちなみに、Android 5以降では使用できますが、サポートライブラリに存在します。つまり、どのバージョンでも使用できます。 そして、現在のプロジェクトでは、これらの補間器が望ましいようです。


コードに戻りましょう。 この膨大なコードのバンドルでは、前回は作成しなかったことが判明しましたが、まだ十分な補間器がありませんでした。

TypeEvaluatorsについては、原則として、通常はいくつかの単純な値をアニメーション化するか、整数または実数のいずれかの数値であり、補間器を設定する必要がないため、手動で設定する必要はほとんどありません。これはすべて認識しています。 ただし、それでも、カスタムビューのレンダリングがPointやRectなどの複雑なオブジェクトに依存する場合、これらの値をアニメーション化するためにシステムで事前定義されたPointFEvaluatorまたはRectEvaluatorを使用することもできます。

また、カスタムTypeEvaluatorを使用して、プリミティブの一部の非典型的な変更を行うことができます。 たとえば、色をアニメーション化する場合。

色が何であるか覚えておきましょう。 これは通常の整数で、各チャンネルにアルファ、赤、緑、青の2色を設定します。 通常のintのようにアニメーション化すると、ある色から別の色への美しい遷移ではなく、信号機または何らかの虹が得られます。

また、独自のTypeEvaluatorsを作成することもできます。これに干渉することはできません。


ArgbEvaluatorなど、典型的なTypeEvaluatorの実装例を見てみましょう。 これはシステムに存在するため、実装する必要はありませんが、優れた実例として役立ちます。

TypeEvaluatorインターフェイスは次のとおりです。 Evaluateメソッドは1つしかありません。分数はパラメーターとして渡されます-これは補間されたアニメーション時間です。 開始値と終了値の両方。

何をする必要がありますか? 開始値と終了値から各チャネルの色を取得する必要があります。 これは最初から行います。これは決勝からです。


そして、0から1までの値を持つ分数に基づいて、アニメーションの現在の値で色がどのように見えるかの値を見つけます。 それが計算方法です。

ObjectAnimatorに移りましょう。 そして、ここでこの質問をすることができます:ValueAnimatorがクライアント開発でほとんど使用されていないと言ったのに、なぜValueAnimatorがどのように機能するかを考慮したのですか? はい、ObjectAnimatorはValueAnimatorの直接の拡張機能であり、ValueAnimatorについて私が言ったことはすべて、ObjectAnimatorについては真実です。ただし、UpdateListenerを使用する必要はありません。 代わりに、ObjectAnimatorは、アニメーション中にある種の可変パラメーターをカプセル化するプロパティの新しい概念を導入します。 これが何であるかを理解します。


コードをもう一度見てみましょう。CrossFadeがObjectAnimatorsでどのように見えるかを見てみましょう。 ここにAnimatorSetを保存しましたが、ObjectAnimatorsは内部に表示されます。 そして、ObjectAnimatorがどのパラメーターで作成されるべきかを見てみましょう。 アニメーション化されたオブジェクトは最初のパラメーターとして渡され、プロパティ(アニメーション化する必要があります)は2番目のパラメーターとして渡されます。 さらに変更可能な値。

アニメーションの継続時間を入力することも残っています。


そして-同じリスナー、そこからは何も得られないので、すべてのコードが膨らみます。


次に、プロパティが内部でどのように見えるかを見てみましょう。 プロパティアルファはシステム内にあるため、手動で実装する必要はありませんが、それが何であり、一般的に何が含まれているかを完全に見ることができます。

ご覧のとおり、Propertyの場合、正しく機能するように2つのメソッドを再定義する必要があります。 したがって、setValueメソッドは、typeevaluatorが計算する新しい値をすべて設定する方法を示します。 したがって、それらはアニメーション化されたオブジェクトに設定されます。 Getメソッドは、アニメーターがこのプロパティのアニメーションの現在の値を知る必要がある場合です。 Getメソッドは、アニメータがアニメーションの初期値を取得する場合に使用できます。

ここで、ValueAnimatorがObjectAnimatorとどのように異なるかを判断しましょう。

ValueAnimatorの結果として得られる値は、Animatorで設定され、UpdateListenerに渡されるとすでに考えています。 APIを備えたObjectAnimatorだけでこれが軽減され、Propertyを使用して必要な値がすべて設定されます。

素晴らしい、プラスがある-コードが少ない。

それでは、プロパティデータをどのように設定するかを見てみましょう。

まず、コードの例のように、プロパティ継承を使用します。 ただし、これを文字列で設定することもできます。 たとえば、アニメーション化されたプロパティとしてアルファ文字列が設定されている場合、アニメーション中にアニメーターはsetAlphaやgetAlphaなどのメソッドがViewオブジェクトに設定されることを期待します。 そのようなメソッドがオブジェクトにそれぞれ存在しない場合、クラッシュします。

また、線を使用してビューの一部をアニメートする場合、Reflectionを使用してビューに入ることを理解することも価値があります。これにより、アニメーションプロセスでオブジェクトを操作および変更するプロセスがさらに遅くなります。

それでは、デフォルトでシステムにすでに存在するプロパティを見てみましょう。これは使用できます。 これはアルファ(透明度)です。これらは、画面上のビューの位置に関連するパラメーターです。これらは、画面の回転とスケーリングに関連するパラメーターです。 そして、もちろん、自分で欲しいプロパティを作成し、それを使用してビューをアニメーション化することもできます。

どうぞ 次に、ViewPorpertyAnimatorがあり、ValueAnimatorに基づいて機能します。その主な利点は、いくつかのビューを単純なプロパティでアニメーション化するための非常に便利なAPIを提供することです。 複数の値をアニメーション化する場合、ObjectAnimatorよりもわずかに高速ですらあります。 しかし、これにはマイナスもあります-シンプルさ。 ViewPorpertyAnimatorを使用してアニメーション化されるカスタム属性を作成することはできません。 最も単純で同じアルファ、位置決め、スケール、回転のみがあります。


ViewPorpertyAnimatorを使用して、クロスフェードメソッドがどのように見えるかを見てみましょう。 ちなみに、これは1つのスライドに入った唯一のクロスフェードコードであり、そのために適しています。

ここではすべてが明確だと思います。 ビューで呼び出されるAnimateメソッドは、ViewPorpertyAnimatorを返します。 次に、それを主張し、Alphaメソッドを呼び出し、このビューに必要な最終値を表示し、アニメーションの継続時間を示し、補間器を指定します。 そして、ここで別のwithEndActionメソッドに注目できます。このメソッドは、アニメーションが完了した後に実行するアクションを決定します。

そのため、ビューの一部をアニメーション化できるかなり多数の方法を既に検討しました。 それらからいつ、どれを使うべきかを決めましょう。

ViewAnimationとDrawableAnimationでは、すべてを大まかに理解する必要があります。 ViewAnimationは絶対に使用しないでください。DrawableAnimationは、他の方法を使用して実際にアニメーションを作成できない場合にのみ、非常に複雑なケースに使用します。 デザイナーに次のように伝えます。「そして、フレームごとのアニメーションを私に流し込んだ」とデザイナーは試み、それを使用します。 しかし、最も興味深いのは詳細に検討します。

クライアント開発のValueAnimatorは、おそらくPropertyを記述できない場合にのみ使用する価値があります。 たとえば、アニメーションオブジェクトにはゲッターがないためPropertyを書き込むことはできませんが、呼び出されないことは確かであり、初期値から最終値までアニメーション化し、定義するのに十分ですDateListener、およびアニメーション中に受け取った新しい値を渡します。 次に、ValueAnimatorを使用できます。

他のすべての場合、および非常に複雑または複雑なアニメーションの場合、アニメーション化されたプロパティまたはアニメーション化されたオブジェクトが多数ある場合、ObjectAnimatorを使用する必要があります。 この場合、ほとんどの場合、複雑なアニメーションの場合は、AnimatorSet内で使用します。

また、いくつかの完全にシンプルなアニメーションには、ViewPropertyAnimatorを使用できます。

予定より早くアニメーションを完成させる必要がある状況はどうですか?

多くの場合、初心者にはこのエラーが発生します。 ViewPropertyAnimatorを使用してある種のアニメーションを開始し、キャンセルする場合はclearAnimationメソッドを呼び出します。 clearAnimationはViewAnimationを使用して設定したアニメーションのキャンセルのみを参照するため、このメソッドは機能しません。また、ViewAnimationを使用しないことに同意したので、役に立たないでしょう。

ViewPropertyAnimatorを使用してアニメーションを開始した場合は、キャンセルする必要があります。 また、最初にビューでAnimateメソッドを呼び出してから、cancelメソッドを呼び出します。

ValueまたはObjectAnimatorの使用を開始したアニメーションをキャンセルする場合は、それらへのリンクを保存し、適切なタイミングでキャンセルを呼び出す必要があります。

現在発生している現在のアニメーションをキャンセルする必要があるのはいつですか? まず、ユーザーは何らかのアクションを通じて、アニメーションを開始した現在のアクションをキャンセルしていることを知らせます。 その後、元に戻すことができ、ビューを初期状態に戻します。 しかし、別の状況があります。

たとえば、ユーザーがこのアクティビティをすべて閉じてこの画面を終了し、Animatorが引き続き機能する場合は、単にコンテキストをリークすることがありますが、これは常にあまり良くありません。 したがって、今回は乗車のように思えても、ValueまたはObjectAnimatorへのリンクを維持することが重要です。あなたを動揺させる必要があります。ほとんど常にAnimatorへのリンクを維持する必要があります。ビューについて話している場合は、現在のアニメーションをキャンセルする必要があります。

view , Measure/Layout, view . , . - , Android 16 2/3 , ? , , layout pass, Measure Layout, , , . , , Measure Layout, , , , . , , , , , .

, , . , Measure Layout — , , , .

? . view ObjectAnimators, Top Bottom, , set Top Bottom , . , , , Layout, , , , , , , .

. , Measure Layout — , - , , . , — Measure/Layout, — , - . , - , , , Measure/Layout. - , . , .

, LayoutTransition, animateLayoutChanges, . ValueAnimator. ? LayoutTransition - ViewGroup, childs ViewGroup, , , . LayoutTransition , , .

LayoutTransition, - , , , LinearLayout, animateLayoutChanges, true, , , , , . . , . layout , LayoutTransition - .

, . . , . - , -, , , -, , .

. ?


LayoutTransition, , LayoutTransition Changing. , childs layout, LayoutTransition, , . LinearLayout, LinearLayouts . , LinearLayouts, , .

, , , . , , , . , layout, , ? LayoutTransition LinearLayout .


. ?

. , - . . - , - . , . , . ? それを理解しましょう。

LayoutTransition - , , childs, , LayoutTransition, , , . , , — setAnimateParentHierarchy, true.

, LinearLayout, , , , .

LinearLayouts, , AnimateParentHierarchy true, view LayoutTransition, , . , , LayoutTransition, , delay, , setAnimateParentHierarchy false, .


. layout. - , .

, LayoutTransition . Appearing Disappearing — view .

Changeappearing Changedisappearing — transitions, . parent childs parent.

Changing, , view.

, , LayoutTransition , - . , , ViewGroup LayoutTransition, , . — .

. , : , view, . . , ImageView , .

, view . , , , , . , view, , view, .

Android -, - , , Transition Framework.

Transition Framework , LayoutTransition. , , Transition, , , . childs, . , LayoutTransition . . Transition Framework . , Android 4.4. transitions Android. Android 5.

, , .


, view, , .

? TransitionSet, transition. ChangeBounds — Transition, layout, layout .

Fade, Fade.

TransitionSet — AnimatorSet, Transition.

beginDelayedTransition, Transition. , , , , Transition, , . , .

, , . LayoutTransition ViewGroup, .

, BeginDelayedTransition, view, layout, .

transitions ? . ChangeBounds Fade . Android 5 , . , - Transition, , .

, Transition — , , . , . , Transition , .

— Slide. , Fade, - . , -, view , - , , . Transition Slide.

, , , . . Slide, TransitionChangeBounds.

Transition, Explode. , - . , , - . , Explode, , , , . API.

ChangeTransform — Transition, view.

ImageView. Transition, ChangeImageTransform. , preview- SkillType ImageView, , , , Transition ImageView.

ChangeImageTransform, ImageView ChangeBounds.

, , , , . , , excludeTarget, ID, , . ID, true.

, , . , , , , , - , ID, view. - , : «, - , , view», excludeTarget, false. ID, view. excludeTarget, excludeChildren.

— , view , , : , view root. addTarget, Transition, view .

ID, view. -, - , removeTarget.


Transition Framework , Transitions, internet- XML. , , Transition. TransitionInflater Java- XML Transition. Transition.


Transition Framework . , layout.

? XML view ID, , Transition Framework , view , . go, layout .

ID - , TransitionName, , , Android 5, Transition Framework view, ID.

Transition Framework Android. , , Support Library, . Fade ChangeBounds Android 4.4, 4.0 4.3. . . , , , , , , , , , , Overview Support Library. , , , , , , .

, - layout : LayoutTransition Transition Framework? LayoutTransition , , - , , , 4.0, . Transition Framework, , , - Android.

, . , , , - , , , . , , , , - .



, . , , , , , . , , , .

, . , - , . view . rocket science . , , , ValueAnimator.

ValueAnimator, ? , , , , , , . , . - , .

Android , Dynamic animation, Physic-based animation. , , , .

, , , , FlingAnimation SpringAnimation. FlingAnimation , - , , , , , . SpringAnimation — - .

, , Dynamic animation .

, , , ValueAnimator ObjectAnimator. , , .

Dynamic animation .

: « ? ?». すべてが非常に簡単です。 , , . .

Dynamic animation . — , .

FlingAnimation «», , . SpringAnimation , , , , , . «».

, , .

, , FlingAnimation. よし! , . . いいね!


, .

, , touch-. , view, Listener RecyclerView, onTouchListener ( , ), RecyclerView Listener, .

velocityTracker — Android, , — , , , , ActionUp, ActionCancel, - view , , , . velocityTracker, computeCurrentvelocity, FlingAnimation, , velocityTracker, , , view , , .

EndListener — , .

, , , onStop.

, , - , Start.

, view? view, - . , , view .

, Dynamic animation.

, Fling. , SpringAnimation, view . , .

, , , , .

, . ( GitHub: bit.ly/2uQPiSY .)


FlingAnimation EndListener , , , , SpringAnimation, SpringForce, , , , , .

, , , , , , - Dynamic Animation.

Dynamic animation. FlingAnimation , , , SpringAnimation, , , - .

, - .

, — , , . . : « ?», , - .

-, , , Transition Framework, ObjectAnimation, ViewPropertyAnimator, Dynamic animation.

, : Android 4.3 . , . . - - . , . .

そして最後の1つ。 , . , . Developer Settings, . , 5x — , . — , , - .

, , - , Android. ItemAnimator, RecyclerView. . ItemAnimator — , , .

ItemAnimator, , , DefaultItemAnimator, RecyclerView. .

AnimatedVectorDrawable, . Android, compatibility- Support Library. - , Android 4, . StackOverflow , AnimatedVectorDrawableCompat .

Activity Fragment Transition — activity . Transition Framework, API .

, . . , . .

: , Telegram

Source: https://habr.com/ru/post/J344296/


All Articles