forceLayout()
の役割とクラスrequestLayout()
のinvalidate()
メソッドについて少し混乱しています。View
彼らはいつ呼ばれますか?
forceLayout()
の役割とクラスrequestLayout()
のinvalidate()
メソッドについて少し混乱しています。View
彼らはいつ呼ばれますか?
François BOURLIEUXとDalvikによって提供された回答をよりよく理解するには、 Arpit Mathurによるこの素晴らしいビュー ライフサイクル図をご覧になることをお勧めします。
invalidate()
ビューの再描画をスケジュールするときに、呼び出しinvalidate()
が行われます。最終的に呼び出されることになりますonDraw
(すぐに呼び出されますが、すぐには呼び出されません)。カスタム ビューがそれを呼び出す場合の例は、テキストまたは背景色のプロパティが変更された場合です。
ビューは再描画されますが、サイズは変わりません。
requestLayout()
サイズに影響するビューの変更がある場合は、 を呼び出す必要がありますrequestLayout()
。これは、このビューだけでなく、親ビューのすべての行でトリガーされonMeasure
ます。onLayout
呼び出しrequestLayout()
は(受け入れられた回答の図が意味するものとは逆に) になることが保証されていないonDraw
ため、通常は と組み合わされinvalidate()
ます。
invalidate();
requestLayout();
この例は、カスタム ラベルのテキスト プロパティが変更された場合です。ラベルのサイズが変わるため、再測定して再描画する必要があります。
forceLayout()
親ビュー グループで呼び出されるがある場合requestLayout()
、その子ビューを再測定して再レイアウトする必要はありません。ただし、子を再測定および再レイアウトに含める必要がある場合は、forceLayout()
その子を呼び出すことができます。直接の親forceLayout()
の と一緒に発生した場合にのみ、子で機能します。requestLayout()
単独で呼び出しても、ビュー ツリーをforceLayout()
トリガーしないため、効果はありません。requestLayout()
の詳細な説明については、この Q&Aをお読みくださいforceLayout()
。
View
ソースコードここでいくつかの応答を見つけることができます: http://developer.android.com/guide/topics/ui/how-android-draws.html
私にとっては、呼び出しinvalidate()
はビューのみを更新し、呼び出しはビューをrequestLayout()
更新して画面上のビューのサイズを計算します。
再描画するビューで invalidate() を使用すると、その onDraw(Canvas c) が呼び出され、 requestLayout() はレイアウト全体のレンダリング (測定フェーズと配置フェーズ) を再度実行します。実行時に子ビューのサイズを変更する場合に使用する必要がありますが、親ビューからの制約などの特定の場合にのみ使用する必要があります (つまり、親の高さまたは幅が WRAP_CONTENT であるため、子を再度ラップする前に測定することを意味します)。
この答えは について正しくありませんforceLayout()
。
コードでforceLayout()
わかるように、ビューを「再レイアウトが必要」としてマークするだけですが、その再レイアウトをスケジュールしたりトリガーしたりしません。再レイアウトは、将来のある時点でビューの親が何らかの理由でレイアウトされるまで発生しません。
forceLayout()
andを使用する場合、さらに大きな問題もありますrequestLayout()
。
forceLayout()
ビューを呼び出したとしましょう。そのビューの子孫を呼び出すと、Android はその子孫の祖先requestLayout()
を再帰的に呼び出します。requestLayout()
問題は、呼び出したビューで再帰が停止することですforceLayout()
。そのため、requestLayout()
呼び出しがビュー ルートに到達することはなく、レイアウト パスがスケジュールされることはありません。ビュー階層のサブツリー全体がレイアウトを待機しておりrequestLayout()
、そのサブツリーのビューを呼び出してもレイアウトは発生しません。requestLayout()
そのサブツリーの外側のビューを呼び出すだけで、呪文が破られます。
(の実装と、forceLayout()
それがどのように影響requestLayout()
するかは壊れていると考えており、コードでその関数を使用しないでください。