回答:
FrançoisBOURLIEUXとDalvikによって提供された回答をよりよく理解するには、Arpit Mathurによるこの素晴らしいビューライフサイクル図をご覧になることをお勧めします。
TextView
。私は多分、彼らが描きたいと思ったView
彼らはそのレイアウト関連のパラメータを変更する前に、最後の時間のために、私たちは異なる順序(に呼び出されて、それらの呼び出しを考えるならば、それは実際にどんな意味がないと、彼らは呼び出しinvalidate()
直後requestLayout()
でTextView
同じように)。多分それはStackOverflowで別の質問に値するでしょう:)?
invalidate()
とrequestLayout()
)を正しく理解していないと思います。これらのメソッドの目的は、(無効化と呼ばれた)View
どのような無効化が発生したかを通知することです。View
これらのメソッドの1つを呼び出した後に、がどのパスをたどるかを決定するようなものではありません。View
-lifecycle-pathの選択の背後にあるロジックは、それ自体を呼び出す適切なメソッドを選択することです。サイズ変更に関連するものがある場合requestLayout()
-呼び出す必要がありますinvalidate()
。サイズ変更なしで視覚的な変更のみがある場合-を呼び出す必要があります。
View
、いくつかの方法で、例えばあなたは、現在の取得LayoutParams
のView
、あなたがそれらを変更、しかし、NOTのいずれかを呼び出すrequestLayout
かsetLayoutParams
(呼び出すrequestLayout
あなたが呼び出すことができ、内部的に)invalidate()
あなたが好きな限り、及びこれView
はメジャーレイアウトプロセスを通過しないため、そのサイズは変更されません。あなたが教えていない場合はView
その大きさが(と変化していることrequestLayout
メソッドの呼び出し)、そしてView
それがなかったと仮定しますと、onMeasure
とonLayout
呼ばれることはありません。
invalidate()
invalidate()
ビューの再描画をスケジュールしたいときに呼び出しが行われます。それはonDraw
(ただし、すぐに、すぐに)最終的に呼び出されています。カスタムビューが呼び出すのは、テキストまたは背景色のプロパティが変更されたときです。
ビューは再描画されますが、サイズは変更されません。
requestLayout()
サイズに影響を与えるビューの変更がある場合は、を呼び出す必要がありますrequestLayout()
。これがトリガーされonMeasure
、onLayout
、親ビューのために、このビューのためではなく、すべての方法のラインアップだけではなく。
呼び出しrequestLayout()
は結果としてonDraw
(受け入れられた回答の図が意味するものとは逆に)になることが保証されていないため、通常はと組み合わされinvalidate()
ます。
invalidate();
requestLayout();
この例は、カスタムラベルのテキストプロパティが変更された場合です。ラベルのサイズが変わるため、再測定して再描画する必要があります。
forceLayout()
requestLayout()
親ビューグループで呼び出されるがある場合、その子ビューを再測定して再レイアウトする必要はありません。ただし、子供を再測定と再レイアウトに含める必要がある場合は、子供を呼び出すことができますforceLayout()
。直接の親forceLayout()
と一緒に発生した場合にのみ、子で機能しrequestLayout()
ます。ビューツリーのアップをforceLayout()
トリガーしないため、それ自体を呼び出しても効果はありませんrequestLayout()
。
の詳細については、このQ&Aをご覧くださいforceLayout()
。
View
ソースコードrequestLayout()
前に呼び出すことができますinvalidate()
。どちらもすぐにレイアウトや描画を行いません。むしろ、最終的に再レイアウトと再描画をもたらすフラグを設定します。
ここにいくつかの応答があります:http : //developer.android.com/guide/topics/ui/how-android-draws.html
私にとってはinvalidate()
、ビューをrequestLayout()
更新するための呼び出しと、ビューを更新するための呼び出しと、画面上のビューのサイズを計算します。
この答えは正しくありませんforceLayout()
。
あなたがのコードで見ることができるようにforceLayout()
ビューに「再レイアウトが必要」とマークされているだけで、再レイアウトのスケジュールやトリガーは行われていません。再レイアウトは、将来のある時点で、ビューの親が他の何らかの理由で配置されるまで発生しません。
forceLayout()
and を使用する場合には、さらに大きな問題がありrequestLayout()
ます。
forceLayout()
ビューを呼び出したとしましょう。requestLayout()
このビューの子孫を呼び出すと、AndroidはrequestLayout()
その子孫の祖先を再帰的に呼び出します。問題は、呼び出したビューで再帰が停止することですforceLayout()
。そのため、requestLayout()
呼び出しがビュールートに到達することはなく、レイアウトパスをスケジュールすることもありません。ビュー階層のサブツリー全体がレイアウトを待機しておりrequestLayout()
、そのサブツリーのビューを呼び出してもレイアウトは発生しません。requestLayout()
そのサブツリーの外側のビューを呼び出すだけで、魔法が解かれます。
私はの実装を検討しますforceLayout()
(そしてそれrequestLayout()
が壊れるのにどのように影響するか、そしてあなたはコードでその関数を決して使用すべきではありません)。
View
自分で問題を実行してデバッグすることで、それを理解しました。
forceLayout()
API:それは実際にレイアウトパスを強制しない、むしろそれだけでフラグ変更で観察されているonMeasure()
が、onMeasure()
いない限り呼ばれませんrequestLayout()
か、明示的にView#measure()
呼ばれています。つまり、forceLayout()
とペアにする必要がありrequestLayout()
ます。一方、forceLayout()
まだ実行する必要があるのに、なぜそれを実行するのrequestLayout()
ですか?
requestLayout()
も行うすべてをforceLayout()
行います。
forceLayout
は理にかなっています。つまり、結局のところ、非常にひどい名前が付けられ、文書化されています。