Сбой при обновлении адаптера в listview

#android #listview

#Android #listview

Вопрос:

Я использую разделенный адаптер. В каждом разделе есть «подадаптер».

У меня возникает проблема, когда я удаляю все разделы и добавляю новые. Если новое количество разделов> старое количество разделов.

 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 ?

Комментарии:

1. Пожалуйста, добавьте код из вашего адаптера.

Ответ №1:

Я предполагаю, что метод не вызывается при обновлении адаптера и вызове adapter.notifyDataSetChanged();

Правильно. getViewTypeCount() вызывается только один раз.

Как я могу решить эту проблему?

Не изменяйте значение getViewTypeCount() для срока службы вашего адаптера.

Могу ли я заставить действие вызвать getViewTypeCount ?

Извините, я не в курсе.

Комментарии:

1. Из javadoc This method will only be called when the adapter is set on the AdapterView

Ответ №2:

Предупреждение о взломе

Если вы используете 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();
}
  

Как вы можете видеть mAdapter.getViewTypeCount() , вызывается только при вызове setAdapter.
Итак, если мы скопируем этот код и переместим его в 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
     }
  

Я понятия не имею, влияет ли это на производительность или переработку, читая это, вы берете на себя всю вину за приведенный выше код.
🙂