Przerysuj pojedynczy wiersz w widoku listy [duplikat]

To pytanie ma już odpowiedź tutaj:

Czy jest możliwe przerysowanie pojedynczego wiersza w ListView? Mam {[0] } z wierszami, które są LinearLayout s. słucham zmiany preferencji i czasami muszę zmienić tylko jeden View wewnątrz LinearLayout jednego wiersza. Czy jest sposób na przerysowanie tego wiersz bez wywołania listview.notifyDatasetChanged()?

Próbowałem zadzwonić do view.invalidate () w widoku (wewnątrz LinearLayout), ale nie zmienia wiersza.
Author: Sufian, 2010-11-02

4 answers

Jak Romain Guy wyjaśnił jakiś czas podczas sesji Google I/O , najskuteczniejszym sposobem aktualizacji tylko jednego widoku w widoku listy jest coś takiego (ten aktualizuje całe DANE 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;
    }

Zakładając, że target jest jednym elementem adaptera.

Ten kod pobiera ListView, a następnie przegląda aktualnie wyświetlane widoki, porównuje element target, którego szukasz z każdym wyświetlanym elementem widoku, a jeśli twój cel jest wśród nich, Pobierz załączając widok i wykonaj adapter getView() w tym widoku, aby odświeżyć wyświetlacz.

Na marginesie invalidate() nie działa tak, jak niektórzy oczekują i nie odświeży widoku tak, jak to robi getView(), notifyDataSetChanged() odbuduje całą listę i zakończy się wywołaniem getview() dla każdego wyświetlanego elementu i invalidateViews() wpłynie również na kilka.

Ostatnia rzecz, można również uzyskać dodatkową wydajność, jeśli tylko musi zmienić potomek widoku wiersza, a nie cały wiersz, jak robi to getView. W takim przypadku poniższy kod może zastąpić list.getAdapter().getView(i, view, list); (przykład zmiany tekstu TextView):

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

W kodzie ufamy.

 105
Author: GriffonRL,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-18 07:13:01

view.invalidate() nie zadziałało dla mnie. Ale to działa jak urok:

Suppose aktualizujesz pozycję "position " w wierszu. if unikaj dziwnych przerysowań, takich jak taniec tekstowy, gdy jesteś aktualizowanie wierszy, których nie ma na ekranie.

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

                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            listView.invalidateViews();
                        }
                    });
            }
 6
Author: Felipe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-05 23:24:27

Romain Guy odpowiedział na to pytanie w " Google IO 2010 the world of ListView" Wideo w tym samym czasie, w którym zadano to pytanie : http://www.youtube.com/watch?feature=player_detailpage&v=wDBM6wVEO70#t=3149s

Więc według Romain Guy, to powinno zadziałać, i myślę, że możemy mu zaufać. Powód, dla którego twój pogląd nie jest przerysowany, jest nieco tajemniczy. Może spróbuj wyłączyć wszystkie opcje pamięci podręcznej dostępne w listView
setAnimationCacheEnabled(false);
setScrollingCacheEnabled(false);
setChildrenDrawingCacheEnabled(false);
setChildrenDrawnWithCacheEnabled(false);
 3
Author: jptsetung,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-22 14:15:53

Umieść jakiś znacznik w wierszu, który chcesz zaktualizować. Jeśli chcesz ponownie narysować ten konkretny widok lub wiersz, wykonaj

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

A następnie

View v = lv.findViewWithTag(tagobject);
A potem robisz co chcesz z widokiem.
 0
Author: user590849,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-14 06:52:43