ListView中的自定义视图与itemViewType

时间:2014-05-29 18:33:56

标签: android performance android-layout android-listview

我的应用程序中有一个ListView。此列表视图的适配器包含多个项目视图类型(大约5到现在),通过它我可以在列表视图中扩展不同类型的行视图。

适配器内充气的所有行视图都是自定义子视图/视图组。

public class CustomView1 extends RelativeLayout {
    Bundle bundle;

    public CustomView1(Bundle bundle) {
        super(context);
        this.bundle = bundle;
        addSubViews(bundle.getBundleList("list"));
    }

    private void addSubViews(ArrayList<Bundle> list) {
         for(Bundle element : list) {
              //add sub views via reflection
              View view = (View) Class.forName(packageName + type).getConstructor(Bundle.class).newInstance(element);
              addView(view);
         }
    }

    //called from getView() in adapter when convertView != null
    public void onRecycle(Bundle bundle) {
         if(bundle != this.bundle) {
             this.bundle = bundle;
             removeAllViews();
             addSubViews(bundle.getBundleList("list"));
         }
    }
}

传递给每个自定义视图的Bundle包含该视图的布局信息。通过这种方式,我可以在任何视图组中创建和添加任何视图/视图组。一切都很好。

现在,当此代码在ListView中运行时出现问题。由于所有视图类型最初都是由适配器创建的,因此适配器会继续创建不同itemViewType的新自定义视图。 如何减少listview中的那些混蛋?任何想法?在列表视图中,所有viewTypes在前5个位置都不同,因此适配器必须创建这些视图,这会使体验变得迟钝。

即使适配器在第5个索引之后回收类似的视图类型convertViews,我使用removeAllViews()清除容器并再次运行此循环,因为从第6个位置开始的传入包的subView包列表可能不同。所以最后,适配器只回收空的ViewGroups。由于subView列表可能包含任何内容(可能在任何元素包中都有一个包列表),我必须执行removeAllViews()以适应再循环convertView中的新子视图树。

我想过使用垂直ScrollView但是预先占用太多内存,并且自定义视图的数量是动态的,可以增加到20个。

应用程序正在运行,但滚动非常糟糕,几乎没有任何可用性,所以它看起来像现在我通过添加如此多的动态行为也没有取得任何成果。请建议我解决这个问题的方法。

我怀疑在CustomView类中使用setLayoutParams可能会停止滚动,因为我在创建后设置了所有视图的宽度/高度。

使用ViewHolder模式

更新#1 getView()代码

ViewHolder holder; 
if(convertView == null) { 
  holder = new ViewHolder(); 
  holder.customView1 = new CustomView1(bundle);
  convertView = holder.customView1; 
  convertView.setTag(holder); 
} else { 
  holder = (ViewHolder)convertView.getTag(); 
} 
holder.customView1.onRecycle(bundle);

1 个答案:

答案 0 :(得分:0)

ListView非常支持不同的View类型。只需确保使用视图持有者模式以避免不稳定的滚动,然后override getViewTypeCount()getItemViewType()

更多细节http://android.amberfog.com/?p=296