2011-05-06 68 views
0

HI all,Android:帶有自定義ArrayAdapter的ListView在長列表上動作 - 定時問題!

我有這個「搜索結果」ListView。 搜索結果可以是不同的「種類」(不同的部分,稱之爲)。 要分離「種類」,我添加一個標題行。 (我知道可擴展列表,但不能用於其他原因)。

在我的getView()中,我檢查一個屬性,如果它被設置,我改變了該行的背景顏色。

問題:當我運行一個只返回幾行(比如15)的查詢時,一切正常。但是當我運行另一個返回的時候,比如說600行,有些東西會變得怪異,並且它隨機地以一定的時間間隔改變背景。當我在調試模式下運行並在中間停止時,同樣的事情發生。

所以,這絕對是一個時間問題。

我在想這可能是由於屏幕鍵盤關閉時不得不重新渲染大列表。

那麼,是適配器的責任?有沒有解決方案?

如果鍵盤出現問題,是否有機制在開始渲染之前告訴列表「等到事物關閉」? (不知道我喜歡那樣,但是比得到一條可愛的小彩虹更好......)

謝謝!

Llappall

-

這裏的適配器和元素的佈局(如下圖):

private class ElementAdapter extends ArrayAdapter<Element> { 
    private ArrayList<Element> rows; 
    private Element.typeEnum type; 

    public ElementAdapter(Context context, int textViewResourceId, ArrayList<Element> rows) { 
    super(context, textViewResourceId, rows); 
    this.rows = rows; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
    View v = convertView; 
    if (v == null) { 
     LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     v = vi.inflate(R.layout.element, null); 
    } 
    Element row = rows.get(position); 
    if (row == null) { 
     return v; 
    } 
    v.setTag(row); 
    type = row.getType(); 
    boolean isSectionType = type == Element.typeEnum.DIV118SECTION || type == Element.typeEnum.APPASECT || 
     type == Element.typeEnum.APPBSECT || type == Element.typeEnum.AZSECT; 

    TextView title = (TextView) v.findViewById(R.id.title); 
    TextView body = (TextView) v.findViewById(R.id.body); 
    if (isSectionType) { 
     body.setMaxLines(5000); 
    } 
    title.setText(row.getTitle()); 
    if (row.getBody() != null) { 
     body.setText(row.getBody()); 
    } 
    if (type == Element.typeEnum.SEARCHLISTHEADER) { 
     v.setBackgroundColor(Color.rgb(230, 230, 250)); 
     title.setBackgroundColor(Color.rgb(230, 230, 250)); 
     body.setBackgroundColor(Color.rgb(230, 230, 250)); 
     star.setBackgroundColor(Color.rgb(230, 230, 250)); 
    } 
    return v; 
    } 
} 

==元LAYOUT ==

<TextView 
    android:id="@+id/body" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:maxLines="1" 
    style="@style/ListItemSubTitle" /> 
</LinearLayout> 

回答

0

如果您在這裏發佈getView()方法,會更容易。 從我所知道的情況來看,您可能會錯誤地使用再循環視圖。 如果未設置屬性,請檢查背景是否更改爲某些內容。 例如:

if (peoperty.isSet()) { 
    changeBackGround(); 
} 

只是由本身是錯誤的,如果你正在重用convertView,由於背景將保持相同的顏色是怎麼回事,當被用於不同的行這一觀點。

必須是這樣的:

if (peoperty.isSet()) { 
    changeBackGround(); 
} else { 
    changeBackgroundToSomethingNeutral() 
} 
+0

我將適配器和佈局附加到原始問題。謝謝你的幫助! – llappall 2011-05-09 16:49:06

0

我帶着隨意重寫代碼爲你,因爲你做了太多怪異的東西。這是我想對你狀況的優化工作的代碼(沒有測試它的任何,而應工作):

if (row == null) { return v; }

private class ElementAdapter extends ArrayAdapter<Element> { 

    public ElementAdapter(Context context, int textViewResourceId, ArrayList<Element> rows) { 
     super(context, textViewResourceId, rows); 
     this.rows = rows; 
    } 

    private final ArrayList<Element> rows; 

    @Override 
    public View getView(final int position, View convertView, final ViewGroup parent) { 
     ViewsHolder holder = null; 
     if (convertView == null) { 
      convertView = LayoutInflater.from(getContext()).inflate(R.layout.element, parent, false); 
      holder = new ViewsHolder(); 
      holder.title = (TextView) v.findViewById(R.id.title); 
      holder.body = (TextView) v.findViewById(R.id.body); 
      convertView.setTag(holder); 
     } else { 
      holder = (ViewsHolder) convertView.getTag(); 
     } 
     final Element row = rows.get(position); 
     final Element.typeEnum type = row.getType(); 
     if (type.equals(Element.typeEnum.DIV118SECTION) || type.equals(Element.typeEnum.APPASECT) || 
        type.equals(Element.typeEnum.APPBSECT) || type.equals(Element.typeEnum.AZSECT)) { 
      body.setMaxLines(5000); 
     } 
     holder.title.setText(row.getTitle()); 
     if (row.getBody() != null) { 
      holder.body.setText(row.getBody()); 
     } else { 
      holder.body.setText(""); 
     } 
     if (type == Element.typeEnum.SEARCHLISTHEADER) { 
      convertView.setBackgroundColor(Color.rgb(230, 230, 250)); 
      holder.title.setBackgroundColor(Color.rgb(230, 230, 250)); 
      holder.body.setBackgroundColor(Color.rgb(230, 230, 250)); 
      //star.setBackgroundColor(Color.rgb(230, 230, 250)); // Where did that come from? 
     } 
     return convertView; 
     } 

    private final class ViewsHolder { 
     public TextView title; 
     public TextView body; 
    } 
} 

原始代碼的音符夫婦是錯的。列表中的任何位置都不應該包含任何空元素。即使你有,也不應該爲該行拋出一些隨機視圖。你在這裏做的是返回「v」,它很可能(可能會是)一些可回收的舊行,仍然顯示舊數據,這會混淆用戶。我做了一個假設,寫代碼時你不會有任何空的元素。

if (row.getBody() != null) { 
    body.setText(row.getBody()); 
} 

幾乎是好的,但同樣,如果你正在重用convertView(這是一些隨機的前一行即不再顯示),那麼,如果身體竟然是空那你就只能顯示舊的數據,這再次會混淆用戶。如果body爲null,只需將該字符串設置爲空。

P.S. 我建議您觀看關於如何使用ListView的提示和技巧:The world of ListView

相關問題