在列表视图中更新适配器时崩溃

发布于 2024-12-11 21:55:34 字数 1619 浏览 0 评论 0原文

我使用 分段适配器。每个部分都有一个“subAdapter”。

当我删除所有部分并添加新部分时,我遇到了问题。如果新的Sections数量>旧的部分数量。

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,则不会出现该问题。

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

Im using a Sectioned adapter. Each section has a "subAdapter".

I get a problem when im removing all sections, and adding new ones. If the new amount of Sections > old amount of sections.

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)

From what I've read this is a problem with getViewTypeCount. Im guessing that the method isn't called when Im updating the adapter and calling adapter.notifyDataSetChanged();

The problem doesn't occur if i set a new instance of the adapter as listAdapter.

How can I solve this problem? Can I force the activity to recall getViewTypeCount ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

っ左 2024-12-18 21:55:34

我猜测当我更新适配器并调用adapter.notifyDataSetChanged();时不会调用该方法;

正确的。 getViewTypeCount() 仅调用一次。

如何解决这个问题?

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

我可以强制 Activity 调用 getViewTypeCount 吗?

据我所知,抱歉。

Im guessing that the method isn't called when Im updating the adapter and calling adapter.notifyDataSetChanged();

Correct. getViewTypeCount() is only called once.

How can I solve this problem?

Do not change the value of getViewTypeCount() for the lifetime of your adapter.

Can I force the activity to recall getViewTypeCount ?

Not that I am aware of, sorry.

不疑不惑不回忆 2024-12-18 21:55:34

黑客警报

如果您使用 Etsy 的 StaggerredGridView(并将代码复制为模块),或者使用扩展 AbsListView 的内容,您可以获得它每当您调用 notifyDataSetChanged() 时调用 getViewTypeCount()

这是原始代码(对于 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
     }

我不知道这是否会影响性能或回收,通过阅读本文,您将承担上述代码的所有责任。
:-)

Hack Alert

If you are using Etsy's StaggerredGridView (and copy the code in as a module), or use something that extends AbsListView you can get it to recall getViewTypeCount() whenever you call notifyDataSetChanged().

Here is the original code (for StaggeredGridView - ExtendableListView.java:

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

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

    requestLayout();
}

As you can see mAdapter.getViewTypeCount() is only called when you call setAdapter.
So if we copy this code and move it to the place notifyDataSetChanged() is called we can update our adapter with new types!

Which is here (for 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
     }

I have no idea if this effects performance or recycling, by reading this you take all blame for the above code.
:-)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文