1

我有带部分的列表,但是这个 ListView 很慢。

我需要任何支架,但我不知道我怎么做。

当我有一种视图时,它很简单,但在这里我遇到了问题。

我创建了持有人,但是当 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;
}
4

3 回答 3

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;
    }
}

注意:已经过测试并且现在可以工作了!

于 2013-03-19T11:43:28.300 回答
0

http://www.youtube.com/watch?v=wDBM6wVEO70。与视图持有者讨论列表视图的性能。

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;
}
于 2013-03-19T11:18:36.583 回答
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;
}
于 2013-03-19T11:25:35.863 回答