2014-01-07 3 views
0

Я следил за this, this и this, чтобы сделать мой ListView лучшими. Собственно, следуя третьей ссылке, я существенно улучшил гладкость прокрутки.Улучшить производительность переустановки ListView

Дело в том, что я использую индивидуальный макет для каждой строки, который содержит 2 ImageViews (один из них неизменный, а второй с двумя возможными назначениями drawables) и два TextViews, поэтому это определение:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:background="@drawable/elem_list" 
    android:orientation="horizontal"> 

    <ImageView 
     android:id="@+id/chanlist_featured" 
     android:layout_width="20dp" 
     android:layout_height="30dp" 
     android:layout_marginTop="8dp" 
     android:contentDescription="@string/desc_gen_image" 
     android:gravity="center" /> 

    <TextView 
     android:id="@+id/chanlist_chan" 
     android:layout_width="0dp" 
     android:layout_height="wrap_content" 
     android:layout_gravity="left" 
     android:layout_weight="13" 
     android:ellipsize="marquee" 
     android:maxLines="2" 
     android:padding="10dp" /> 

    <LinearLayout 
     android:layout_width="40dp" 
     android:layout_height="match_parent" 
     android:orientation="vertical"> 

     <TextView 
     android:id="@+id/chanlist_usercount" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center" 
     android:paddingTop="10dp" 
     android:ellipsize="marquee" 
     android:gravity="center" 
     android:maxLines="2" 
     android:textSize="11sp" /> 

     <ImageView 
     android:layout_width="10dp" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center" 
     android:paddingTop="8dp" 
     android:contentDescription="@string/desc_gen_image" 
     android:background="@drawable/user" /> 

    </LinearLayout> 
</LinearLayout> 

Хорошо, никаких проблем до сих пор. Поэтому я определил свой индивидуальный ArrayAdapter метод GetView() которого состоит в следующем:

И здесь возникает проблема: я пытаюсь показать около 300 элементов списка. Как я уже сказал, список прокручивается плавно (и большинство сообщений, которые я нашел об улучшении производительности ListViews, говорят об этом), но время между вызовом инициализации адаптера (новый MyOwnArrayAdapter() ...) и визуализацией список огромен (около 15-20 секунд). Я могу просто приукрасить его, показывая индикатор выполнения, но мне интересно, не делаю ли я что-то неэффективное здесь, поскольку я думаю, что 300 элементов - это не так много.

Любые советы приветствуются!

---------- ---------- EDIT

я в том числе конструктор:

public class StableArrayAdapter<T> extends ArrayAdapter<T> { 
    final private Context context; 
    final private int resourceId; 
    final private List<T> objects; 
    final Drawable star, star_off; 

    // There I store the objects to include in the list 
    final private HashMap<T, Integer> mIdMap = new HashMap<T, Integer>(); 
    // I had to Override some methods related to the observers, that's why I store this 
    final private ArrayList<DataSetObserver> observers = new ArrayList<DataSetObserver>(); 

    // Constructor 
    public StableArrayAdapter(final Context context_, final int resourceId_, final List<T> objects_) { 
    super(context_, resourceId_, objects_); 

    this.context = context_; 
    this.resourceId = resourceId_; 
    this.objects = objects_; 

    for (int i = 0; i < objects.size(); i++) 
     mIdMap.put(objects.get(i), i); 

    star = context.getResources().getDrawable(R.drawable.checkbox_star); 
    star_off = context.getResources().getDrawable(R.drawable.checkbox_star_down); 
    } 

    ... 
} 
+0

Если прокрутка не является проблемой, ваша проблема не в 'getView()'. Он находится в инициализации адаптера. Как вы получаете данные, которые заполняют ListView? Добавьте этот код в свой пост. –

+0

Данные, переданные в StableArrayAdapter(), обрабатываются URL-адресом, который содержит эти 300 элементов.Я не считаю, что это займет время, поскольку это отдельная задача (в фоновом потоке, кстати). Как только я получил эти элементы, я передаю их конструктору, который я редактировал в своем сообщении. – nKn

ответ

0

Наконец я получил его. В принципе, это не имело ничего общего с инициализацией или методом getView(). Как и во время обработки конструктора StableArrayAdapter(), я мог бы сделать некоторые дополнительные вещи в paralell, я начал Thread() до вызова new StableArrayAdapter(), и чтобы синхронизировать результат этого потока и инициализации, я забыл, что я объявил CountDownLatch(), поэтому в основном код ниже инициализации адаптера ожидал, что поток вызовет метод countDown().

Извините, ребята, и в то же время благодарю вас, из кода в исходном сообщении никто не мог этого знать (я непреднамеренно омрачил эту часть, думая, что это не важно).

В то же время я надеюсь, что это может помочь кому-то или хотя бы дать ключ.

0

Просто блуждающий - конвертировании Список в HashMap (с каким-то idex?), Чем в getView(), вы делаете getItem (position), вероятно, ищите HashMap для значения (!!!) == position? Почему бы не сохранить исходный список и получить элементы данных прямо из него?

+0

Как вы можете видеть, класс StableArrayAdapter параметризирован (T), потому что я хочу использовать его для нескольких действий с той же логикой, но с другим типом данных, и избегать определения одного расширения ArrayAdapter для каждого из них. Я использую HashMap, потому что он очень эффективен, но для некоторых из этих действий (а не для этого особо) мне нужно иметь стабильные идентификаторы (т. Е. Элементы должны иметь один и тот же идентификатор даже после обновления HashSet). – nKn

0

Я собираюсь угадать, что проблема в цикле , который вы выполняете в конструкторе. Интересно, реализуют ли какие-то List реализации свои базовые данные каждый раз, чтобы удовлетворить методу size(). Как насчет кеширования?

int size = objects.size(); 
for (int i = 0; i < size; i++) { 
     mIdMap.put(objects.get(i), i); 
} 

Альтернативно может использовать Iterator

+0

В основе вашего комментария я поместил объект журнала непосредственно перед этим и сразу после этого цикла, и потребовалось 0.12 сек. обрабатывать его, поэтому я предполагаю, что это не проблема. Однако это кажется странным, потому что содержимое списка появляется за секунды ПОСЛЕ того, как он покинул конструктор ... – nKn

Смежные вопросы