私は困惑している問題に遭遇しており、誰かが私にいくつかの指針を与えてくれることを望んでいました.
カスタム ViewGroup (実際には RelativeLayout を含む FrameLayout) を使用してイベント カレンダーをレンダリングするアプリケーションに取り組んでいます。カレンダー内のイベントは、イベントの期間とそれを含むビューのサイズに応じたサイズのビューとして表されます。
含まれている FrameLayout のサイズが変更されたときに発生する問題が発生しています。現在の実装では、イベントを表すすべてのビューを削除し、新しいビューを追加して、FrameLayout の現在のサイズに基づいてサイズを計算しようとします。この作業は、FrameLayout でオーバーライドされる View の onSizeChanged() メソッドを介してトリガーされます。
ビューのサイズが変更されると、このコードが実行され、ビューが更新されますが、実際には画面にレンダリングされるものはありません... FrameLayout に含まれるビューは単に表示されません。Hierarchyviewer ツールでビューを読み込むと、それらはビュー ツリーの一部であり、概観の本来あるべき位置に概説されますが、表示されません。(ビューは FrameLayout の最初のレンダリングで表示されることに注意してください...ビューが消えるのは、サイズ変更後にのみです。)
サイズ変更中のイベントの順序は次のようになります。
onMeasure()
onMeasure()
onSizeChanged()
onLayout()
ビュー(onSizeChanged()内)をリセットした後にrequestLayout()を呼び出しても効果がないようです。ただし、requestLayout() を呼び出す前に遅延を発生させると、ビューが表示されます。スレッドを生成してスリープ状態にするか、単純に requestLayout() を呼び出すダミー ボタンを作成し、サイズ変更後にそれを押すか、または onSizeChanged() の最後に配置されたこの醜いハックでさえ、この遅延を引き起こすことができます。
post(new Runnable() {
public void run() {
requestLayout();
}
});
このハックを使用すると、含まれているビューが表示され、イベントの順序は次のようになります。
onMeasure()
onMeasure()
onSizeChanged()
onLayout()
onMeasure()
onMeasure()
onLayout()
そのため、(ビュー ツリーが変更された後に) 2 回目の測定パスを強制すると、含まれているビューが本来あるべき姿で表示されるようになります。なぜ requestLayout() の呼び出しを遅らせると、これが起こるのかは謎です。
誰かが私が間違っていることについての指針を提供できますか?
一部のコードを見ずにこれを理解するのはやや難しいことを認識しているため、私の問題を示す小さなサンプル アプリケーションを作成し、Github で利用できるようにしました。
https://github.com/MichaelSims/ViewGroupResizeTest
上記のハックは、別のブランチにコミットされています。
https://github.com/MichaelSims/ViewGroupResizeTest/tree/post-runnable-hack
追加情報を提供できる場合は、お知らせください。事前に感謝します。