2009-08-24 11 views
11

Załaduję dane z Kursora do listy, ale mój Listview nie wyświetla się "gładko". Dane zmieniają się, gdy przeciągam w górę iw dół na pasku zadań w moim ListView. Niektóre elementy wyglądają jak duplikaty na mojej liście. I hava "złożone ListView" (dwa textview, jeden widok obrazu) Tak użyłem newView(), bindView() do wyświetlania danych. Czy ktoś może mi pomóc?Jak załadować Listview "płynnie" w Androidzie

Odpowiedz

11

Opiszę, jak uzyskać taki problem, jaki masz. Być może to ci pomoże.

Tak, w liście adaptera masz taki kod:

public View getView(int position, View contentView, ViewGroup arg2) 
    { 
     ViewHolder holder; 

     if (contentView == null) { 
      holder = new ViewHolder(); 
      contentView = inflater.inflate(R.layout.my_magic_list,null); 
      holder.label = (TextView) contentView.findViewById(R.id.label); 
      contentView.setTag(holder); 
     } else { 
      holder = (ViewHolder) contentView.getTag(); 
     } 

     holder.label.setText(getLabel()); 

     return contentView; 
    } 

Jak widać, mamy ustawioną wartość elementu listy dopiero po pobraniu uchwyt.

Ale jeśli przenieść kod do powyżej if:

holder.label.setText(getLabel()); 

tak będzie wyglądać po jak poniżej:

if (contentView == null) { 
    holder = new ViewHolder(); 
    contentView = inflater.inflate(R.layout.my_magic_list,null); 
    holder.label = (TextView) contentView.findViewById(R.id.label); 
    holder.label.setText(getLabel()); 
    contentView.setTag(holder); 
} 

będzie mieć swój aktualny zachowanie aplikacji z elementu listy powielania.

Prawdopodobnie to pomoże.

+0

To również pomaga. Dzięki – Dennie

7

ListView to podstępna bestia.

Najpierw drugie pytanie: widzisz duplikaty, ponieważ ListView ponownie korzysta z widoków przez convertView, ale nie upewniasz się, że chcesz zresetować wszystkie aspekty przekonwertowanego widoku. Upewnij się, że ścieżka kodu dla convertView!=null poprawnie ustawia wszystkie dane dla widoku i wszystko powinno działać poprawnie.

będziemy chcieli metoda getView() wyglądać mniej więcej tak jak poniżej, jeśli używasz widoki niestandardowe:

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    final MyCustomView v = convertView!=null ? (MyCustomView)convertView : new MyCustomView(); 
    v.setMyData(listAdapter.get(position)); 
    return v; 
} 

Jeśli nie używasz swój własny pogląd, wystarczy zastąpić wywołanie new MyCustomView() z wezwanie do inflater.inflate(R.layout.my_layout,null)

Co do pierwszego pytania, będziemy chcieli oglądać techtalk Romain w sprawie wykonania ListView tutaj: http://code.google.com/events/io/sessions/TurboChargeUiAndroidFast.html

od swoich rozmów i w kolejności im portance z własnego doświadczenia,

  • Zastosowanie convertView
  • Jeśli masz zdjęcia, nie skalować obrazy w locie. Użyj Bitmap.createScaledBitmap stworzyć skalowany bitmapę i umieścić, że do swoich poglądów
  • użyć ViewHolder więc nie trzeba zadzwonić kilka findViewByIds() za każdym razem
  • Zmniejsz złożoność widoków w ListView. Im mniej subviews, tym lepiej. RelativeLayout jest o wiele lepszy niż na przykład LinearLayout. I używaj go, jeśli implementujesz niestandardowe widoki.
+0

Przepraszamy, ale używam newView(), bindView() do wyświetlania danych. czy to ten sam problem? – Dennie

+0

Myślę, że znajdę coś przydatnego w filmie, dzięki za udostępnienie! – Dennie

1

Mam również do czynienia z tym problemem, ale w moim przypadku użyłem wątków do pobierania zewnętrznych obrazów. Ważne jest, aby bieżący wątek roboczy nie zmieniał obrazu, jeśli jest ponownie użyty!

public View getView(int position, View vi, ViewGroup parent) { 
ViewHolder holder; 
String imageUrl = ...; 

if (vi == null) { 
    vi = inflater.inflate(R.layout.tweet, null); 
    holder = new ViewHolder(); 
    holder.image = (ImageView) vi.findViewById(R.id.row_img); 
    ... 
    vi.setTag(holder); 
} else { 
    holder = (ViewHolder) vi.getTag();  
} 
holder.image.setTag(imageUrl); 
... 
DRAW_MANAGER.fetchDrawableOnThread(imageUrl, holder.image); 
} 

A potem na sprowadzania wątku Robię ważną czek:

final Handler handler = new Handler() { 
@Override 
public void handleMessage(Message message) { 
    // VERY IMPORTANT CHECK 
    if (urlString.equals(url)) 
     imageView.setImageDrawable((Drawable) message.obj); 
}; 

Thread thread = new Thread() { 

@Override 
public void run() { 
    Drawable drawable = fetchDrawable(urlString); 
    if (drawable != null) { 
     Message message = handler.obtainMessage(1, drawable); 
     handler.sendMessage(message); 
    } 
}}; 
thread.start(); 

Można by również zrezygnować z bieżącego wątku, jeśli ich zdaniem jest wykorzystywany (jak to opisano here), ale zdecydowałem się na to, ponieważ chcę wypełnić pamięć podręczną do późniejszego wykorzystania.

0

Możesz zobaczyć powtarzający się tekst w wielu wierszach, jeśli postępujesz z nim w niewłaściwy sposób. Ostatnio trochę o tym piszę - zobacz here. Poza tym możesz rzucić okiem na ListView performance optimization. Zwykle jest to spowodowane ponownym użyciem widoku i widziałem to już kilka razy.

1

Tylko jedna wskazówka: NIGDY nie używaj przezroczystego tła układu przedmiotów - znacznie spowalnia wydajność

Powiązane problemy