4

いくつかのカスタム ビューを含む複雑なフレーム レイアウトがあります。主なビューはグラフです。

グラフのオーバーレイは、ユーザーがグラフ上でドラッグして特定のデータ ポイントに関する詳細情報を読み取ることができる十字ポインターを表すカスタム ビューです。

フレーム レイアウトはすべてのタッチ イベントをキャプチャし、各子ビューで「ヒット テスト」メソッドを呼び出して、タッチがそのビューにあったかどうかを判断し、タッチ イベントを適切なビューにディスパッチします。

ユーザーが十字線に触れてドラッグすると、タッチイベントを十字線に渡し、それを使用して位置を更新し、それ自体を無効にします。

すべてが機能しています...

これらの子ビューのいずれかを無効にすると、レイアウト内のすべてのビューが再描画されます。開発者向けオプションで「画面の更新を表示」をオンにしているので、これを知っています。含まれている FrameLayout を無効にすることは決してありません - または少なくとも、故意ではありません。

確かに、レイアウトを処理するアクティビティはレイアウトを無効にせず、子ビューに親への参照はありません。

それ以来、私はコードを投稿していません。a) これが通常の動作であるかどうかはわかりません。b) たくさんあります。c) 通常の動作でない場合、コードのどの部分に問題があるのか​​わかりません。もちろん、ご要望があれば何でも承ります。

私の最小 API は 2.3.3 で、ターゲットは 4.0 です。これは両方のバージョンで発生するため、コードに問題があると思われますが、どこから始めればよいでしょうか?

何が起こっているのかについての手がかりはありますか?

4

4 に答える 4

6

View親に依存するため、「それ自体」を描画する方法はありません(メソッドCanvasを介してクリップおよび変換されdispatchDrawます)。無効化には、ビューツリー全体を無効にする必要があります-これがあなたが探している答えです:)

のソースを調べるとViewGroup、2 つの重要なメソッドがあることがわかります: dispatchDraw(描画イベントをその子にディスパッチする責任があります) とdrawChild(によって呼び出されdispatchDraw、子がどのように描画されるかを指定できます)。無効化領域を指定Viewする がありますが、無効化を開始するチェックはありません。RectF私が理解している限り、無効化View(クロス)が画面全体を占めないようにする必要があるため、再描画は実際にかかる部分のみになります。

于 2013-07-06T11:16:29.657 に答える
2

正しく理解している場合、クロスヘア ビューの線は画面全体をカバーします。つまり、上から下への 1 本の垂直線と、左から右への 1 本の水平線です。

十字線の中心を変更しても他のビューが再描画されない場合、画面はすぐに以前の十字線の位置からの古い線で雑然とします。あなたはこれを望んでいないので、他のビューも自分自身を再描画することを嬉しく思います.

必要に応じて、「ダーティ」な四角形を指定してinvalidate(Rect dirty)を呼び出すことができます。これにより、その四角形の完全に外側にあるビューは再描画されません。その場合はあなた次第ですが、その長方形の外側を変更しないでください。

于 2013-07-06T12:41:45.423 に答える