2014-01-07 10 views
0

我跟着this,thisthis使我的ListView具有儘可能最好的性能。實際上,在第三條鏈接之後,我大大提高了滾動的平滑度。提高ListView賦值的性能

問題是我爲每行包含2個ImageViews(其中一個不變,第二個有兩個可能的繪圖分配)和兩個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個元素不是那麼多。

任何意見讚賞!

---------- ----------編輯

我包括構造:

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()的數據解析了一個具有這300個項目定義的URL。我不計算這需要的時間,因爲它是一個單獨的任務(在後臺線程,順便說一句)。一旦我得到這些項目,我將它們傳遞給我在我的帖子中編輯的構造函數。 – nKn

回答

0

最後我得到了它。基本上,它與初始化和getView()方法無關。在處理StableArrayAdapter()構造函數的過程中,我可以在並行中做一些其他的事情,我在調用new StableArrayAdapter()之前啓動了一個Thread(),並且爲了同步這個線程的結果和初始化,我忘記了我已經聲明瞭CountDownLatch(),所以基本上適配器初始化下方的代碼正在等待該線程調用countDown()方法。

對不起傢伙,同時感謝你,從最初的帖子中的代碼可以知道這(我無意中忽略了這部分認爲它不重要)。

同時,我希望這可以幫助某人,或者至少提供線索。

0

只是徘徊 - 你轉換列表到一個HashMap(有一些idex?),而不是在getView()你getItem(位置)可能搜索HashMap的值(!!!)==位置?爲什麼不保留原始列表並從中獲取數據元素?

+0

正如你所看到的,StableArrayAdapter類是參數化的(T),這是因爲我想將它用於幾個具有相同邏輯但不同數據類型的活動,並避免爲每個類定義一個ArrayAdapter擴展。我使用HashMap是因爲它非常高效,但對於其中一些活動(不是特別的),我需要具有穩定的ID(即使更新HashSet後元素也必須具有相同的ID)。 – nKn

0

我要猜測問題出在您在構造函數中循環的List循環中。我想知道是否有一些List實現每次都會遍歷其基礎數據集以滿足方法size()。那麼緩存呢?

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

或者可以使用一個Iterator

+0

在你的評論的基礎上,我把一個Log對象放在那個循環之前和之後,它花了0.12秒。來處理它,所以我認爲這不是問題。然而,這似乎很奇怪,因爲列表的內容在離開構造函數後出現秒數...... – nKn