web-dev-qa-db-ja.com

次のコード行が実行される直前にビューを強制的に再描画する方法

その子ビューの1つ(ImageButton)がクリックされたときの背景色を変更したいLinearLayoutがあります。私はこれを行うことはできますが、すぐにはできません-変更は画面で発生します(後でonResumeの呼び出し中と思われます)。背景が設定された後、次のコード行が実行される前に、レイアウトを強制的に再描画する方法を知りたいのですが。ボタンのOnClickListenerのonClickメソッドは次のとおりです。

_public void onClick(View v) {

  LinearLayout parentLayout = (LinearLayout) v.getParent();
  parentLayout.setBackgroundResource(R.color.my_color);
  SystemClock.sleep(1000); //ms

}
_

Sleepコマンドは、再描画がその前または後に発生するかどうかをテストするためにそこにあります。結果:後。このトピックに関するほとんどの質問( herehere など)は、ビューでinvalidate()を使用するように言っています。コマンドparentLayout.invalidate();parentLayout.postInvalidate();、およびparentLayout.refreshDrawableState();をバックグラウンドラインとスリープラインの間に使用しましたが、すべて役に立ちませんでした。再描画は、sleepコマンドの後も発生します。誰でもすぐにそれを実現する方法を教えてもらえますか?

その他の有用な情報:LinearLayoutはListViewの行にバインドされ、上記のOnClickListenerは、アクティビティ自体ではなく、SimpleCursorAdapterを拡張するカスタムクラスにあります。 (これにより、ListViewの各行にリスナーを設定できます。)

21
pvans

さて、私はようやくこの問題の解決策を見つけました、そしてそれは簡単です。 OnTouchListenerで実行するべきだったのに、OnClickLIstenerで描画可能な変更を実行していたことが問題だったようです。 ACTION_DOWNを探すボタンにOnTouchListenerを設定してから、その親レイアウトでsetBackgroundColorを実行すると、すぐに変更が発生します。

代わりの、堅牢性の低いソリューションは この投稿 から得られます。親レイアウトの背景にセレクターをxmlで割り当てることができます。次に、上記のOnTouchListenerで、そのレイアウトに対してsetPressed(true)を実行します。セレクターは、コードでビューのプロパティを直接変更するよりもはるかに自由度が少ないため、優れたソリューションではありません。たとえば、別のボタンを押してレイアウトの背景を別の色に設定することはできませんでした。

これに関する提案を手伝ってくれた人々に感謝します!

2
pvans

直後にforceLayout()を呼び出してdraw(canvas)を試すことができます。 onLayout()onMeasuredraw()またはonDraw()をオーバーライドしなかった場合、デフォルトの実装が実行されます。これに関する唯一の問題は、キャンバスを取得するか、手動で作成する必要があることです。

Androidは通常の更新の外に描画されないように特別に設計されているため、このアプローチを追求することは強くお勧めしません。invalidate()がすぐに発生しないことは正しいですが、それは再描画を促す最も安全で最適な方法です。更新以外で描画を処理する場合は、Androidを使用すると、SurfaceHolderクラスでこれを行うことができます。

3
Fuzzical Logic

変更を加え、listview.invalidate();を呼び出します。これらの変更をUIに反映するには

1
Jana