更新listview中的适配器时崩溃

时间:2011-10-27 08:29:19

标签: android listview

我正在使用Sectioned adapter。每个部分都有一个“subAdapter”。

我删除所有部分并添加新部分时出现问题。如果新的部分数量>旧的部分。

10-27 08:08:33.789: ERROR/AndroidRuntime(21550): java.lang.ArrayIndexOutOfBoundsException
10-27 08:08:33.789: ERROR/AndroidRuntime(21550):     at android.widget.AbsListView$RecycleBin.addScrapView(AbsListView.java:5283)
10-27 08:08:33.789: ERROR/AndroidRuntime(21550):     at android.widget.AbsListView.trackMotionScroll(AbsListView.java:4092)
10-27 08:08:33.789: ERROR/AndroidRuntime(21550):     at android.widget.AbsListView.onTouchEvent(AbsListView.java:2523)
10-27 08:08:33.789: ERROR/AndroidRuntime(21550):     at android.widget.ListView.onTouchEvent(ListView.java:3733)
10-27 08:08:33.789: ERROR/AndroidRuntime(21550):     at android.view.View.dispatchTouchEvent(View.java:3885)
10-27 08:08:33.789: ERROR/AndroidRuntime(21550):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:903)
10-27 08:08:33.789: ERROR/AndroidRuntime(21550):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942)
10-27 08:08:33.789: ERROR/AndroidRuntime(21550):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942)
10-27 08:08:33.789: ERROR/AndroidRuntime(21550):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942)

据我所知,这是getViewTypeCount的一个问题。我猜测在更新适配器并调用adapter.notifyDataSetChanged();

时不调用该方法

如果我将适配器的新实例设置为listAdapter,则不会出现此问题。

我该如何解决这个问题?我可以强制活动调用getViewTypeCount吗?

2 个答案:

答案 0 :(得分:2)

  

我猜测在更新适配器并调用adapter.notifyDataSetChanged();

时不调用该方法

正确。 getViewTypeCount()只被调用一次。

  

我该如何解决这个问题?

请勿在适配器的生命周期内更改getViewTypeCount()的值。

  

我可以强制活动调用getViewTypeCount吗?

不是我知道,抱歉。

答案 1 :(得分:0)

黑客警报

如果您使用的是Etsy的StaggerredGridView(并将代码作为模块复制),或者使用extends AbsListView的内容,您可以随时调用getViewTypeCount()致电notifyDataSetChanged()

以下是原始代码(适用于StaggeredGridView - ExtendableListView.java

@Override
public void setAdapter(final ListAdapter adapter) {
    // ... other code

    if (mAdapter != null) {
        mAdapter.registerDataSetObserver(mObserver);
        mRecycleBin.setViewTypeCount(mAdapter.getViewTypeCount());
    }

    requestLayout();
}

如您所见,只有在调用setAdapter时才会调用mAdapter.getViewTypeCount()。 因此,如果我们复制此代码并将其移动到调用的地方notifyDataSetChanged(),我们可以使用新类型更新我们的适配器!

这是(StaggeredGridView - ExtendableListView.java

    class AdapterDataSetObserver extends DataSetObserver {

        private Parcelable mInstanceState = null;

        @Override
        public void onChanged() {
            // other code

            mRecycleBin.clearTransientStateViews();
            mRecycleBin.setViewTypeCount(mAdapter.getViewTypeCount()); // ADD THIS

            // other code
            requestLayout();
        }

        // more methods
     }

我不知道这会影响性能还是回收利用,通过阅读本文,你会对上述代码负责。     : - )