2015-02-11 26 views
7

Niedawno napotkano problem, w którym animacja o nieokreślonym numerze ProgressBar użyta wewnątrz wiersza ListView stała się niestabilna. Krótko mówiąc, mam ListView, gdzie każdy wiersz zawiera ProgressBar. Animacje wyglądają świetnie, dopóki nie przewijam; od tego momentu co najmniej jeden z ProgressBar będzie miał animację przerywaną.Wydajność z posuwistym przebiegiem w przypadku użycia w ListView

Czy ktoś wie, jak rozwiązać ten problem?

http://imgur.com/EMoRGnJ

widoku dla rzędu ListView

<?xml version="1.0" encoding="utf-8"?> 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <ProgressBar 
     android:indeterminate="true" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" /> 

</LinearLayout> 

prosty zwyczaj ArrayAdapter

public class MyAdapter extends ArrayAdapter { 

    List list; 

    public MyAdapter(Context context, List objects) { 
     super(context, 0, objects); 
     list = objects; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 

     if(convertView == null) { 
      convertView = ((LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.list_row, parent, false); 
     } 

     return convertView; 
    } 
} 

OnCreate() sposobu aktywność próbki

@Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_my); 

     ListView listView = (ListView)findViewById(R.id.list_view); 
     ArrayList<Integer> data = new ArrayList<Integer>(Arrays.asList(1,2,3,4,5,6,7,8,9,0,11,12,13,14,15,16,17)); 
     MyAdapter adapter = new MyAdapter(this, data); 

     listView.setAdapter(adapter); 
    } 

Bug logged (zawiera przykładowy projekt): https://code.google.com/p/android/issues/detail?id=145569&thanks=145569&ts=1423673226

Odpowiedz

0

Spróbuj wprowadzić view holder pattern i sprawdź wydajność.

Utwórz statyczną klasę ViewHolder z paskiem postępu.

static class ViewHolder { 
    ProgressBar progress; 
} 

iw swoim getView() masz znaleźć uchwyt widok z widoku tylko wtedy, gdy convertView jest null, inaczej wziąć go ze znacznikiem sprawującego viewHolder. W ten sposób nadpisujesz nowy widok tylko wtedy, gdy convertView ma wartość null, w przeciwnym razie używasz widoków przechowywanych w twoim znaczniku viewholder. Prosty samouczek można znaleźć here.

+3

W tym przypadku nie sądzę wzór widok posiadacz pomoże. Zazwyczaj wzorzec uchwytu widoku jest używany do zmniejszenia liczby wywołań 'findViewById', co może negatywnie wpłynąć na wydajność (zazwyczaj w przypadku przewijania listy). W tym przykładzie nigdy nie nazywam 'findViewById', więc użycie wzorca widoku nie wygląda na to, że rozwiąże problem. –

+1

@Eric Farraro masz rację. Ale jestem ciekawy, czy RecyclerView zachowuje się tak samo. Czy przetestowałeś go za pomocą LinearLayoutManager? – cybergen

+1

@cybergen, po twojej sugestii, spróbowałem również prostego RecyclerView/LinearLayoutManager. Wygląda na to, że działa znacznie lepiej i nie zaobserwowałem tego samego błędu w animacji. Wygląda na to, że błąd może w szczególności dotyczyć animacji ListView/ProgressBar. –

0

dzieje się to po raz pierwszy, jeśli zamkniesz i ponownie otworzysz aplikację, nie zauważysz tego.

Czy sprawdziłeś w starszych wersjach, takich jak kitkat?

I nie tworzyć LayoutInflater w getView(), tworzyć raz w konstruktorze i używać go w constuctor