web-dev-qa-db-ja.com

ビューでinvalidate()を実行する必要がある場合

この質問 に対する私の答えは受け入れられましたが、Viewを無効にする必要があるのはいつですか?

少し考えてから、shouldが次のように動作することに気付きました:

  • 「すべて」の実際の描画は、onResume()の後に発生します
  • 「自由な」時間に画面の一部を再描画できますが、invalidated(およびその下にあるすべてのもの)のみを再描画できます

したがって、onResume()の後に何かを変更すると(たとえば、ボタンのクリックへの応答として、変更されたViewinvalidate()する必要があります)。

ただし、 この質問 のscanaの説明から、それはそれよりも複雑でなければならず、どの方法を使用するかによって異なります。

例えば。使用するかどうか

lastClicked.setImageBitmap();

または

lastClicked.setImageResource();

したがって、ビューでinvalidate()を実行する必要があり、実際にどのように機能するのですか?

42
mjaskowski

通常、システムはウィジェットのサイズ変更、非表示、表示、その他の多くを自動的に処理しますが、描画されたピクセルまたはバッキングデータの基礎となるバッファが変更された場合、または古い場合は問題が発生する場合があります(ビューまたは生データセットが変更されます)。これは、OSがデータが特定の方法で変更されたことを知る方法がないために発生します。

描画を処理しているこれらのケースでは、基になるデータが良好な状態ではないことをシステムにWidget.invalidate()で通知する必要があり、再描画はメインスレッドのキューに入れられますあなたが言ったように。システムの実装とAndroidバージョンによってシステムによって変更が追跡されるものは異なりますが、私が通常行うことはシステムリソース(バイト配列、文字配列、リソースインデックス、コンテキスト)は追跡されず、invalidateが必要です。それ以外はすべてシステムによって処理されます。

22
Srdjan Grubor

(いくつかの回答を受け入れることを検討してください)

通常、invalidate()は「画面に再描画」を意味し、ビューのonDraw()メソッドの呼び出しの結果です。そのため、何かが変更され、画面に反映する必要がある場合は、invalidate()を呼び出す必要があります。ただし、組み込みウィジェットの場合、自分で呼び出す必要はほとんどありません。ウィジェットの状態を変更すると、内部コードは必要に応じてinvalidate()を呼び出し、変更が画面に反映されます。たとえば、TextView.setText()を呼び出すと、多くの内部処理を行った後(画面にテキストが収まるか、省略される必要があるかなど)、TextViewinvalidate()が返る前にsetText()を呼び出します。他のウィジェットでも同様です。

カスタムビューを実装する場合、バッキングモデルが変更されるたびにinvalidate()を呼び出し、ビューを再描画する必要があります。また、状態を変更してからinvalidate()を呼び出し、状態を再度変更するなど、単純なアニメーションを作成するためにも使用できます。

75
Nikolay Elenkov

TextPaintを描きたいときにこの問題が発生しました!私のコードは

    canvas.drawPaint(textPaintNumber)
    canvas.drawText("MyText", 30F, 63F, textPaintNumber)

最初の糸くずを取り除き、問題は解決しました

    canvas.drawText("MyText", 30F, 63F, textPaintNumber)
0
Maryam Azhdari

画面上の描画は頻繁に行われるプロセスであり、ビューを更新するときはいつでも、その変更を伝播して再描画し、そのような変更権を通知する必要があることに注意してください。 invalidate()はトリガーメソッドであり、変更を表示するビューの再描画を強制します。

0
Remario