web-dev-qa-db-ja.com

リストビューで単一行を再描画します

ListViewで単一の行を再描画することは可能ですか?行がListViewsであるLinearLayoutがあります。設定の変更を聞いて、1行のView内のLinearLayoutを1つだけ変更する必要がある場合があります。 listview.notifyDatasetChanged()を呼び出さずにその行を再描画する方法はありますか?

ビュー(LinearLayout内)でview.invalidate()を呼び出そうとしましたが、行を再描画しません。

40
Falmarri

Romain Guy しばらく説明したGoogle I/Oセッション の間に戻ったとき、リストビューで1つのビューのみを更新する最も効率的な方法は次のようなものです(これはViewデータ全体を更新します):

_ListView list = getListView();
int start = list.getFirstVisiblePosition();
for(int i=start, j=list.getLastVisiblePosition();i<=j;i++)
    if(target==list.getItemAtPosition(i)){
        View view = list.getChildAt(i-start);
        list.getAdapter().getView(i, view, list);
        break;
    }
_

targetがアダプターの1つのアイテムであると仮定します。

このコードはListViewを取得してから、現在表示されているビューを参照し、探しているtargetアイテムと表示されている各ビューアイテムを比較します。そのビューでアダプターgetView()を実行して、表示を更新します。

サイドノートinvalidate()は一部の人々が期待するようには機能せず、getView()のようにビューを更新しないため、notifyDataSetChanged()はリスト全体を再構築し、終了します表示されたすべてのアイテムに対してgetview()を呼び出し、invalidateViews()を呼び出すと、束にも影響します。

最後に、getViewのように行全体を変更するのではなく、行ビューの子のみを変更する必要がある場合、パフォーマンスが向上する可能性があります。その場合、次のコードでlist.getAdapter().getView(i, view, list);を置き換えることができます(TextViewテキストを変更する例):

_((TextView)view.findViewById(R.id.myid)).setText("some new text");
_

コードでは信頼しています。

106
GriffonRL

view.invalidate()は私には機能しませんでした。しかし、これは魅力のように機能します。

行の位置「position」を更新しているとします。 ifは、画面にない行を更新するときにテキストが踊るなど、奇妙な再描画を避けます。

            if (position >= listView.getFirstVisiblePosition()
                && position <= listView.getLastVisiblePosition()) {

                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            listView.invalidateViews();
                        }
                    });
            }
6
Felipe

Romain Guyは、「Google IO 2010 The ListViewの世界」ビデオでこの質問に答えた正確な時間に答えました: http://www.youtube.com/ watch?feature = player_detailpage&v = wDBM6wVEO70#t = 3149s

Romain Guyによると、それはうまくいくはずで、私たちは彼を信頼できると思います。

ビューが再描画されない理由は、少し不思議です。 listViewで使用可能なすべてのキャッシュオプションを無効にしてみてください。

setAnimationCacheEnabled(false);
setScrollingCacheEnabled(false);
setChildrenDrawingCacheEnabled(false);
setChildrenDrawnWithCacheEnabled(false);
3
jptsetung

更新する行にタグを配置します。特定のビューまたは行を再描画したい場合

ListView lv = (ListView)findViewById(....)

その後

View v = lv.findViewWithTag(tagobject);

そして、あなたはビューであなたがやりたいことをします。

0
user590849