Приложение cra sh из-за java .lang.IndexOutOfBoundsException: обнаружено несоответствие. Неправильный вид держателя адаптера positionViewHolder в RecyclerView - PullRequest
0 голосов
/ 23 апреля 2020

Ранее я сталкивался с этой проблемой и решил ее путем создания пользовательского LinearLayoutManager и использования его для моего RecyclerView. Но снова эта проблема возникла и не получить никакой подсказки о том, как ее решить. Все обновления и уведомления для адаптера выполняются в потоке пользовательского интерфейса.

Может кто-нибудь помочь мне решить эту проблему.

Код адаптера

using System.Collections.Generic;
using Android.Support.V7.Widget;
using Android.Views;
using TabApplications.Applications.Navigation.Models;

namespace HMI_Common.Adapters.Navigation.AddressSearch
{
    public class NaviAddressItemAdapter : RecyclerView.Adapter
    {
        private List<AddressDetailEntity> _addressSearchItems;

        private List<AddressSuggestionEntry> _addressSuggestionEntries;

        private List<FTSTokenElement> _searchCriteriaEntities;

        private readonly INaviAddressItemClickListener _addressItemClickListener;

        private const int CountryItemType = 0, DestinationItemType = 1, AddressSuggestionType = 2;

        private bool _isForCountryItemType, _isForFederalStateType, _isForAddressSuggestion;

        private readonly bool _isCountrySelectionAvailable;

        private readonly int _backButtonLayoutResourceID = -1;

        private readonly NaviEnums.NaviMarket _currentNaviMarket;

        public NaviAddressItemAdapter(List<AddressDetailEntity> addressItems, NaviEnums.NaviMarket naviMarket, 
            INaviAddressItemClickListener listener, bool isCountryAvailable, int backButtonLayoutID) : 
            this(naviMarket, listener, isCountryAvailable, backButtonLayoutID)
        {
            _addressSearchItems = addressItems;
        }

        public NaviAddressItemAdapter(List<AddressSuggestionEntry> addressItems, NaviEnums.NaviMarket naviMarket, 
            INaviAddressItemClickListener listener, bool isCountryAvailable, int backButtonLayoutID) : 
            this(naviMarket, listener, isCountryAvailable, backButtonLayoutID)
        {
            _addressSuggestionEntries = addressItems;
        }

        private NaviAddressItemAdapter(NaviEnums.NaviMarket naviMarket, INaviAddressItemClickListener listener, bool isCountryAvailable, int backButtonLayoutID)
        {
            _currentNaviMarket = naviMarket;

            _addressItemClickListener = listener;

            _backButtonLayoutResourceID = backButtonLayoutID;

            _isCountrySelectionAvailable = isCountryAvailable;

            _searchCriteriaEntities?.Clear();

            _searchCriteriaEntities = null;

            _searchCriteriaEntities = new List<FTSTokenElement>();
        }

        public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
        {
            switch (GetItemViewType(position))
            {
                case CountryItemType:

                    ((NaviCountryItemViewHolder)holder).DisplayCountryItemData(_addressSearchItems[position], position, 
                        _isCountrySelectionAvailable, _isForFederalStateType, _addressSearchItems.Count - 1);

                    break;

                case DestinationItemType:

                    ((NaviLocationItemViewHolder)holder).DisplayAddressItemData(_addressSearchItems[position], position, _addressSearchItems.Count - 1);

                    break;

                case AddressSuggestionType:

                    ((NaviLocationItemViewHolder)holder).DisplaySuggestionItemData(_addressSuggestionEntries[position], 
                        position, _searchCriteriaEntities, _addressSuggestionEntries.Count - 1);

                    break;
            }
        }

        public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
        {
            switch (viewType)
            {
                case CountryItemType:

                    var countryItemView = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.view_browsing_track, parent, false);

                    return new NaviCountryItemViewHolder(parent.Context, countryItemView, _addressItemClickListener, _backButtonLayoutResourceID);

                case DestinationItemType:
                case AddressSuggestionType:

                    var addressItemView = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.view_browsing_meta, parent, false);

                    return new NaviLocationItemViewHolder(parent.Context, _currentNaviMarket, addressItemView, 
                        _addressItemClickListener, viewType == AddressSuggestionType, _backButtonLayoutResourceID);

                default:

                    return null;
            }
        }

        public override int ItemCount => _isForAddressSuggestion ? _addressSuggestionEntries.Count : _addressSearchItems.Count;

        public void UpdateAddressListItems(List<AddressDetailEntity> updatedAddressItems)
        {
            _addressSearchItems = updatedAddressItems;

            if(ItemCount > 0)
            {
                NotifyDataSetChanged();
            }
        }

        public void UpdateAddressSuggestionsItems(List<AddressSuggestionEntry> updatedAddressItems)
        {
            var existingSuggestionsAvailable = null != _addressSuggestionEntries ? ItemCount : 0;

            _addressSuggestionEntries = updatedAddressItems;

            if(ItemCount > 0)
            {
                if (existingSuggestionsAvailable == 0)
                {
                    NotifyDataSetChanged();
                }
                else
                {
                    NotifyItemRangeInserted(existingSuggestionsAvailable, updatedAddressItems.Count - 1);
                    NotifyItemChanged(existingSuggestionsAvailable - 1);
                }
            }
        }

        public override int GetItemViewType(int position)
        {
            if (_isForCountryItemType)
            {
                return CountryItemType;
            }

            return _isForAddressSuggestion ? AddressSuggestionType : DestinationItemType;
        }

        public List<AddressDetailEntity> GetDisplayedAddressSearchItems()
        {
            return _addressSearchItems;
        }

        public List<AddressSuggestionEntry> GetDisplayedAddressSuggestionsItems()
        {
            return _addressSuggestionEntries;
        }

        public void UpdateIsForCountryLevelSearch(bool isForCountryLevelSearch)
        {
            _isForCountryItemType = isForCountryLevelSearch;
        }

        public void UpdateIsForFederalStateType(bool isForFederalState)
        {
            _isForFederalStateType = isForFederalState;
        }

        public bool IsAddressSearchResultsItemsDisplayed()
        {
            if(!_isForCountryItemType && !_isForFederalStateType && !_isForAddressSuggestion 
                && null != _addressSearchItems && _addressSearchItems.Count > 0)
            {
                return true;
            }

            return false;
        }

        public void UpdateIsForAddressSuggestion(bool isForSuggestion)
        {
            _isForAddressSuggestion = isForSuggestion;

            if (!isForSuggestion)
            {
                _addressSuggestionEntries?.Clear();
            }
        }

        public void ClearDisplayedSearchItems()
        {
            _addressSearchItems?.Clear();
            _addressSuggestionEntries?.Clear();
        }

        public void UpdateSearchCriteriaEntities(List<FTSTokenElement> criteriaItems)
        {
            _searchCriteriaEntities?.Clear();

            _searchCriteriaEntities = null;

            _searchCriteriaEntities = new List<FTSTokenElement>(criteriaItems);
        }

        public void RemoveViewEvents(RecyclerView.ViewHolder appropriateViewHolder)
        {
            if (null != appropriateViewHolder)
            {
                if (appropriateViewHolder is NaviCountryItemViewHolder)
                {
                    ((NaviCountryItemViewHolder)appropriateViewHolder).RemoveViewEvents();
                }
                else if (appropriateViewHolder is NaviLocationItemViewHolder)
                {
                    ((NaviLocationItemViewHolder)appropriateViewHolder).RemoveViewEvents();
                }
            }
        }
    }
}

Код для инициализации адаптера

private void DisplayAddressDetailEntries(List<AddressDetailEntity> addressDetailEntities, bool isForCountryItemDisplay = false)
        {
            if (null == _addressItemAdapter)
            {
                _addressItemAdapter = new NaviAddressItemAdapter(addressDetailEntities, _navigationBackend?.GetNaviMarket() ?? NaviEnums.NaviMarket.Europe, 
                    this, IsCountryLevelSearchAvailable(), 
                    ((NavigationBaseActivity) Activity)._backButtonInfoLayout.Id);

                _addressItemsRecyclerView.SetAdapter(_addressItemAdapter);
            }

            _addressItemAdapter.UpdateIsForCountryLevelSearch(isForCountryItemDisplay);

            _addressItemAdapter.UpdateIsForFederalStateType(_isForFederalStatesSearch);

            _addressItemAdapter.UpdateIsForAddressSuggestion(false);

            _addressItemAdapter.UpdateAddressListItems(addressDetailEntities);

            _addressItemAdapter.UpdateSearchCriteriaEntities(_searchCriteriaEntities);

            DisplayLoadingView(false);

            if (!isForCountryItemDisplay && !_isFirstScroll)
            {
                DisplayAddressResultsAnnotations(true);
            }

            if (_isAddressResultsDisplayedForFirstTime)
            {
                _isAddressResultsDisplayedForFirstTime = false;

                _navigationBackend.VerifyCurrentHUSystemLanguage();
            }
        }

        private void DisplayAddressSuggestionEntries(List<AddressSuggestionEntry> addressSuggestionEntries)
        {
            if(null != _addressItemAdapter && _addressItemAdapter.IsAddressSearchResultsItemsDisplayed())
            {
                return;
            }

            if (null == _addressItemAdapter)
            {
                _addressItemAdapter = new NaviAddressItemAdapter(addressSuggestionEntries, _navigationBackend?.GetNaviMarket() ?? NaviEnums.NaviMarket.Europe, 
                    this, IsCountryLevelSearchAvailable(),
                    ((NavigationBaseActivity)Activity)._backButtonInfoLayout.Id);

                _addressItemsRecyclerView.SetAdapter(_addressItemAdapter);
            }

            _addressItemAdapter.UpdateIsForCountryLevelSearch(false);

            _addressItemAdapter.UpdateIsForFederalStateType(false);

            _addressItemAdapter.UpdateIsForAddressSuggestion(true);

            _addressItemAdapter.UpdateAddressSuggestionsItems(addressSuggestionEntries);

            DisplayLoadingView(false);

            if (null != Activity)
            {
                ((NavigationBaseActivity)Activity).RemoveAddressResultsAnnotations(isCurrentLocationToBeShown: true, isKeyboardToBeRemoved: false);
            }
        }

Исключение

54614: 54613 2020/04/22 19:42:43.876064 1530.7664 80 RSER ANDR LOGA 666 log info verbose 1 --------- beginning of crash
54615: 54614 2020/04/22 19:42:43.876118 1530.7665 81 RSER ANDR LOGA 666 log error verbose 1 04-22 14:12:43.866 1526 1526 E AndroidRuntime: FATAL EXCEPTION: main
54616: 54615 2020/04/22 19:42:43.876135 1530.7665 82 RSER ANDR LOGA 666 log error verbose 1 04-22 14:12:43.866 1526 1526 E AndroidRuntime: Process: com.daimler.rse.ntg6, PID: 1526
54617: 54616 2020/04/22 19:42:43.876150 1530.7666 83 RSER ANDR LOGA 666 log error verbose 1 04-22 14:12:43.866 1526 1526 E AndroidRuntime: java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder{aa13176 position=25 id=-1, oldPos=-1, pLpos:-1 no parent} android.support.v7.widget.RecyclerView{655ce4e I.ED.V... .......D 0,128-1326,925 #7f09020d app:id/rvList}, adapter:md5802e7c015aa94524afab2f053beb78c2.NaviAddressItemAdapter@106c06a, layout:md593dc4a3d225f231fc4cef6d7741b0b60.CustomLinerLayoutManager@484a07c, context:md59d95dbab71941e137ef724fbceda5f0e.NavigationBaseActivity@8ab1e87
54618: 54617 2020/04/22 19:42:43.876165 1530.7666 84 RSER ANDR LOGA 666 log error verbose 1 04-22 14:12:43.866 1526 1526 E AndroidRuntime: at android.support.v7.widget.RecyclerView$Recycler.validateViewHolderForOffsetPosition(RecyclerView.java:5447)
54619: 54618 2020/04/22 19:42:43.876180 1530.7666 85 RSER ANDR LOGA 666 log error verbose 1 04-22 14:12:43.866 1526 1526 E AndroidRuntime: at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5629)
54620: 54619 2020/04/22 19:42:43.876194 1530.7666 86 RSER ANDR LOGA 666 log error verbose 1 04-22 14:12:43.866 1526 1526 E AndroidRuntime: at android.support.v7.widget.GapWorker.prefetchPositionWithDeadline(GapWorker.java:285)
54621: 54620 2020/04/22 19:42:43.876209 1530.7667 87 RSER ANDR LOGA 666 log error verbose 1 04-22 14:12:43.866 1526 1526 E AndroidRuntime: at android.support.v7.widget.GapWorker.flushTaskWithDeadline(GapWorker.java:342)
54622: 54621 2020/04/22 19:42:43.876236 1530.7667 88 RSER ANDR LOGA 666 log error verbose 1 04-22 14:12:43.866 1526 1526 E AndroidRuntime: at android.support.v7.widget.GapWorker.flushTasksWithDeadline(GapWorker.java:358)
54623: 54622 2020/04/22 19:42:43.876251 1530.7667 89 RSER ANDR LOGA 666 log error verbose 1 04-22 14:12:43.866 1526 1526 E AndroidRuntime: at android.support.v7.widget.GapWorker.prefetch(GapWorker.java:365)
54624: 54623 2020/04/22 19:42:43.876265 1530.7667 90 RSER ANDR LOGA 666 log error verbose 1 04-22 14:12:43.866 1526 1526 E AndroidRuntime: at android.support.v7.widget.GapWorker.run(GapWorker.java:396)
54625: 54624 2020/04/22 19:42:43.876280 1530.7668 91 RSER ANDR LOGA 666 log error verbose 1 04-22 14:12:43.866 1526 1526 E AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:790)
54626: 54625 2020/04/22 19:42:43.876294 1530.7668 92 RSER ANDR LOGA 666 log error verbose 1 04-22 14:12:43.866 1526 1526 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:99)
54627: 54626 2020/04/22 19:42:43.876308 1530.7668 93 RSER ANDR LOGA 666 log error verbose 1 04-22 14:12:43.866 1526 1526 E AndroidRuntime: at android.os.Looper.loop(Looper.java:164)
54628: 54627 2020/04/22 19:42:43.876322 1530.7668 94 RSER ANDR LOGA 666 log error verbose 1 04-22 14:12:43.866 1526 1526 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:6518)
54629: 54628 2020/04/22 19:42:43.876336 1530.7669 95 RSER ANDR LOGA 666 log error verbose 1 04-22 14:12:43.866 1526 1526 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
54630: 54629 2020/04/22 19:42:43.876350 1530.7669 96 RSER ANDR LOGA 666 log error verbose 1 04-22 14:12:43.866 1526 1526 E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:483)
54631: 54630 2020/04/22 19:42:43.876364 1530.7669 97 RSER ANDR LOGA 666 log error verbose 1 04-22 14:12:43.866 1526 1526 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:811)
54655: 54654 2020/04/22 19:42:44.053564 1530.9443 111 RSER ANDR LOGA 666 log info verbose 1 04-22 14:12:44.040 1244 5620 I am_crash: [1526,0,com.daimler.rse.ntg6,953728589,java.lang.IndexOutOfBoundsException,Inconsistency detected. Invalid view holder adapter positionViewHolder{aa13176 position=25 id=-1, oldPos=-1, pLpos:-1 no parent} android.support.v7.widget.RecyclerView{655ce4e I.ED.V... .......D 0,128-1326,925 #7f09020d app:id/rvList}, adapter:md5802e7c015aa94524afab2f053beb78c2.NaviAddressItemAdapter@106c06a, layout:md593dc4a3d225f231fc4cef6d7741b0b60.CustomLinerLayoutManager@484a07c, context:md59d95dbab71941e137ef724fbceda5f0e.NavigationBaseActivity@8ab1e87,RecyclerView.java,5447]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...