2013-03-19 21 views
1

我有列表的部分,但這個ListView是非常緩慢的。Android SecionList和Holder

我需要任何持有人,但我不知道我該如何做到。

當我有一種類型的視圖很簡單,但在這裏我有問題。

創建持有人,但是當ListView控件顯示時,我看到:

「影片名稱」, 「標題」, 「標題」, 「項」, 「項」

「影片名稱」,「稱號」, 「標題」, 「項」

「影片名稱」, 「標題」, 「標題」, 「項」, 「項」, 「項」

這是我的代碼:

public class EntryAdapter extends ArrayAdapter<Item> { 

private ArrayList<Item> items; 
private LayoutInflater vi; 
Context context; 
private String nazwa; 

public EntryAdapter(Context context,ArrayList<Item> items, String nazwa) { 
    super(context,0, items); 
    this.items = items; 
    this.context = context; 
    this.nazwa = nazwa; 
    vi = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
} 

我的看法:

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

    final Item i = items.get(position); 
    if (i != null) { 
     if(i.isSection()){ 
      SectionItem si = (SectionItem)i; 
      convertView = vi.inflate(R.layout.list_item_section, null); 

      convertView.setOnClickListener(null); 
      convertView.setOnLongClickListener(null); 
      convertView.setLongClickable(false); 

      final TextView sectionView = (TextView) convertView.findViewById(R.id.list_item_section_text); 
     }else{ 
       Obiekt ei = (Obiekt)i; 
       convertView = vi.inflate(R.layout.row_list, null); 
       final TextView title = (TextView)convertView.findViewById(R.id.row_tytul); 
       final TextView odleglosc = (TextView)convertView.findViewById(R.id.row_odleglosc); 
       final ImageView obrazek = (ImageView)convertView.findViewById(R.id.row_ikona_mala); 
       final LinearLayout pole = (LinearLayout)convertView.findViewById(R.id.LinearLayout1); 

     } 
    } 
    return convertView; 
} 

回答

2

我有部分名單,但這個ListView的很慢。

你總是在你的getView()方法中膨脹一個新視圖。 充氣視圖通常需要很長時間。

您想通過檢查'convertView'是否爲空來重新使用以前的視圖。這會提高性能。注意,你也必須實現getItemViewType()getViewTypeCount()因爲你有兩種不同的觀點:

public class MyAdapter extends ArrayAdapter<Item> { 

    private List<Item> items; 
    private int TYPE_SECTION = 0; 
    private int TYPE_OBIEKT = 1; 
    private static LayoutInflater vi; 

    public MyAdapter(Context context, List<Item> _items) { 
     super(context, 0); 
     vi = (LayoutInflater) context.getSystemService(Service.LAYOUT_INFLATER_SERVICE); 
     items = _items; 
    } 

    @Override 
    public int getCount() { 
     return items.size(); 
    } 


    /** 
    * @see android.widget.BaseAdapter#getViewTypeCount() 
    * Determines how many different views you have 
    */ 
    @Override 
    public int getViewTypeCount() { 
     return 2; // We have two different kinds of views 
    } 

    /** 
    * @see android.widget.BaseAdapter#getItemViewType(int) 
    */ 
    @Override 
    public int getItemViewType(int position) { 
     Item item = items.get(position); 
     if (item.isSection()) 
      return TYPE_SECTION; 

     return TYPE_OBIEKT; 
    } 

    /** 
    * @see android.widget.ArrayAdapter#getView(int, android.view.View, android.view.ViewGroup) 
    */ 
    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 

     // Get the item 
     final Item item = items.get(position); 

     if (getItemViewType(position) == TYPE_SECTION) { 

      // Return a SectionView object 
      return getSectionView(position, convertView, parent, (SectionItem) item); 
     } 

     // Return an Obiekt object 
     return getObiektView(position, convertView, parent, (Obiekt) item); 
    } 

    /** 
    * SectionView specific 
    * 
    * @param position 
    * @param convertView 
    * @param parent 
    * @param item 
    * @return 
    */ 
    public View getSectionView(int position, View convertView, ViewGroup parent, SectionItem item) { 

     SectionHolder holder; 
     if(convertView == null){ 

      holder = new SectionHolder(); 

      // Inflate a new View 
      convertView = vi.inflate(R.layout.list_item_section, null); 
      holder.sectionView = (TextView) convertView.findViewById(R.id.list_item_section_text); 

      // Set the ObiektHolder as the tag, to retrieve it for re-using 
      convertView.setTag(holder); 

     } else { 
      holder = (SectionHolder) convertView.getTag(); 
     } 

     // Holder is never null here 
     holder.sectionView.setText(item.getSectionTitle()); 

     return convertView; 

    } 

    public View getObiektView(int position, View convertView, ViewGroup parent, Obiekt item) { 

     ObiektHolder holder; 
     if(convertView == null){ 

      holder = new ObiektHolder(); 

      // Inflate a new View 
      convertView = vi.inflate(R.layout.row_list, null); 
      holder.title = (TextView)convertView.findViewById(R.id.row_tytul); 
      holder.odleglosc = (TextView)convertView.findViewById(R.id.row_odleglosc); 
      holder.obrazek = (ImageView)convertView.findViewById(R.id.row_ikona_mala); 
      holder.pole = (LinearLayout)convertView.findViewById(R.id.LinearLayout1); 

      // Set the ObiektHolder as the tag, to retrieve it for re-using 
      convertView.setTag(holder); 

     } else { 
      holder = (ObiektHolder) convertView.getTag(); 
     } 

     // Holder is never null here 
     holder.title.setText(item.getObiektTitle()); 

     return convertView; 
    } 

    private static class SectionHolder { 
     TextView sectionView; 
    } 

    private static class ObiektHolder { 
     TextView  title; 
     TextView  odleglosc; 
     ImageView  obrazek; 
     LinearLayout pole; 
    } 
} 

注:測試和現在的工作!

+0

我有錯誤的位置: java.lang.ClassCastException:EntryAdapter $ SectionViewHolder不能EntryAdapter $ ItemViewHolder com.edytor.ruciane.lista.EntryAdapter.getView(EntryAdapter.java:90) – Unmerciful 2013-03-20 22:48:52

+0

也可以看看這個帖子:HTTP :/ /stackoverflow.com/questions/4777272/android-listview-with-different-layout-for-each-row – Entreco 2013-03-21 18:51:42

+0

我modiefied答案。我測試了它,並確認它可以工作。您還需要定義您擁有的不同視圖的數量,請參閱修改的代碼示例。更多問題?不要猶豫,問我。祝你好運 – Entreco 2013-03-21 19:26:43

0

http://www.youtube.com/watch?v=wDBM6wVEO70。與視圖持有者討論listview的性能。

http://developer.android.com/training/improving-layouts/smooth-scrolling.html。在下面的標題保持視圖對象視圖中的持有人

挺直從文檔的鏈接看看文檔:

頻繁的ListView的滾動過程中您的代碼可能調用findViewById(),它可以放慢表現。即使適配器返回回收的充氣視圖,您仍然需要查找元素並進行更新。圍繞重複使用findViewById()的方法是使用「視圖持有者」設計模式。

查看者的示例。

@Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
    // TODO Auto-generated method stub 
    ViewHolder holder; 

     if (convertView == null) { 
        convertView = mInflater.inflate(R.layout.list, null); 
        convertView.setLayoutParams(new AbsListView.LayoutParams(LayoutParams.FILL_PARENT, 
          LayoutParams.WRAP_CONTENT)); 
        // Creates a ViewHolder and store references to the two children views 
        // we want to bind data to. 
        holder = new ViewHolder(); 
        holder.t1=(TextView) convertView.findViewById(R.id.textView1); 
        holder.t2 = (TextView) convertView.findViewById(R.id.textView2); 
        holder.t3 = (TextView) convertView.findViewById(R.id.textView3); 

        convertView.setTag(holder); 
       } else { 
        // Get the ViewHolder back to get fast access to the TextView 

        holder = (ViewHolder) convertView.getTag(); 
       } 
       holder.t1.setText("set text") 
       holder.t2.setText("set text2"); 
       holder.t3.setText("set text3"); 
       return convertView; 
    } 
} 


class ViewHolder 
{ 
    TextView t1,t2,t3; 
} 
+0

這不適用於sectionList ... – Unmerciful 2013-03-19 11:34:21

0

首先,您必須檢查convertView是否已經膨脹。如果它已經膨脹,你可以回收它,你不必再膨脹它。那就是你獲得表現的地方。

例子:

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

    View itemView = null; 

    // not inflated 
    if (convertView == null) { 
     LayoutInflater inflater = (LayoutInflater) parent.getContext() 
      .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     itemView = inflater.inflate(R.layout.list_item_section, null); 
    } 
    // already inflated 
    else { 
     itemView = convertView; 
    } 

    // get your textview's etc. 

    return itemView; 
}