NotifyItemRangeChanged () вызывает сбой RecyclerView Android

макетирование:

HorizontalScrollView-parent, holding RV[
    RecyclerView=>(GridLayoutManager) (orientation verticle)]

Что в основном будет делать двустороннюю прокрутку. Этот пользовательский интерфейс создан для ТВ. Строка с фокусом в этой сетке покажет дополнительные детали, а другие строки - нет. Поэтому всякий раз, когда в onFocusChange происходит смена фокуса с одной строки на другую, я изменяю datasetAdapter и вызываю notifyItemRangeChanged().

Это отлично работает, когда длина строк превышает длину экрана по вертикали, то есть с возможностью вертикальной прокрутки. Сбой происходит, скажем, если количество строк меньше (например, 4).

Ошибка:

    java.lang.IllegalArgumentException: parameter must be a descendant of this view
at android.view.ViewGroup.offsetRectBetweenParentAndChild(ViewGroup.java:5937)
at android.view.ViewGroup.offsetDescendantRectToMyCoords(ViewGroup.java:5866)
at android.widget.HorizontalScrollView.isWithinDeltaOfScreen(HorizontalScrollView.java:1168)
at android.widget.HorizontalScrollView.onSizeChanged(HorizontalScrollView.java:1569)
at android.view.View.sizeChange(View.java:19719)
at android.view.View.setFrame(View.java:19680)
at android.view.View.layout(View.java:19583)
at android.view.ViewGroup.layout(ViewGroup.java:6053)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1791)
at android.widget.LinearLayout.layoutHorizontal(LinearLayout.java:1780)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1546)
at android.view.View.layout(View.java:19586)
at android.view.ViewGroup.layout(ViewGroup.java:6053)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1791)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1635)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1544)
at android.view.View.layout(View.java:19586)
at android.view.ViewGroup.layout(ViewGroup.java:6053)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1791)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1635)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1544)
at android.view.View.layout(View.java:19586)
at android.view.ViewGroup.layout(ViewGroup.java:6053)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1080)
at android.view.View.layout(View.java:19586)
at android.view.ViewGroup.layout(ViewGroup.java:6053)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at android.view.View.layout(View.java:19586)
at android.view.ViewGroup.layout(ViewGroup.java:6053)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1791)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1635)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1544)
at android.view.View.layout(View.java:19586)
at android.view.ViewGroup.layout(ViewGroup.java:6053)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at android.view.View.layout(View.java:19586)
at android.view.ViewGroup.layout(ViewGroup.java:6053)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1791)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1635)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1544)
at android.view.View.layout(View.java:19586)
at android.view.ViewGroup.layout(ViewGroup.java:6053)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at com.android.internal.policy.DecorView.onLayout(DecorView.java:758)
at android.view.View.layout(View.java:19586)
at android.view.ViewGroup.layout(ViewGroup.java:6053)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2484)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2200)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1386)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6733)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
at android.view.Choreographer.doCallbacks(Choreographer.java:723)
at android.view.Choreographer.doFrame(Choreographer.java:658)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)

Я попытался вызвать notifydatasetchange, но это вернет getAdapterPosition = -1, что не приведет к изменению фокуса с одной строки на другую.

Поскольку длина кода адаптера превышает длину символа, установленную stackoverflow, я предоставляю ссылку на диск для того же. Код макета адаптера и просмотрщика

Нет сбоев при вертикальной прокрутке NotifyItemRangeChanged () вызывает сбой RecyclerView Android

Сбой при вертикальной прокрутке NotifyItemRangeChanged () вызывает сбой RecyclerView Android

Вы можете выложить свой код, адаптер вы написали

Eranga Gamagedara 26.10.2018 11:29
эта ссылка может вам помочь
sanemars 26.10.2018 12:15

спасибо, проверил их, к сожалению, не имеет отношения ко мне.

DJphy 26.10.2018 12:20

Не могу помочь только с трассировкой стека, прикрепленной к вопросу.

hardartcore 26.10.2018 12:27

@hardartcore Я добавлю код адаптера и код макета просмотрщика, так ли?

DJphy 26.10.2018 12:37

Попробуйте это: your_scrollview_object.setDescendantFocusability(ViewGroup.F‌​OCUS_BEFORE_DESCENDA‌​NTS);

Ümañg ßürmån 26.10.2018 12:48

@ Ümañg ßürmån спасибо, все та же ошибка

DJphy 26.10.2018 13:31

Не могли бы вы приложить снимок экрана к проблеме. и меня больше беспокоит ваш комментарий «Авария происходит, скажем, если меньше строк (например, 4).» - Хотел просмотреть пользовательский интерфейс.

Jitesh Mohite 27.10.2018 08:31

@jiteshmohite, пожалуйста, проверьте добавленные скриншоты

DJphy 28.10.2018 10:57

@DJphy: ReclerView содержит только четыре элемента на втором снимке экрана?

Jitesh Mohite 28.10.2018 16:25

@jiteshmohite да, любое количество строк меньше вертикальной длины экрана, при попытке прокрутки с использованием фокуса происходит сбой, отлично работает, если присутствует большее количество элементов (строк)

DJphy 29.10.2018 11:47

@DJphy Я не уверен, поможет ли это, но вам следует без промедления связать представления в onBindViewHolder, потому что именно тогда RecyclerView выполняет обновления своих представлений впоследствии. Я подозреваю, что если вы привяжете свои представления к Handler.postDelayed, ваша привязка может не работать или столкнуться с неожиданным поведением. Поэтому попробуйте удалить блок задержки, и вам, вероятно, придется найти другой способ асинхронной загрузки данных.

Aaron 30.10.2018 07:08
12
12
724
1

Ответы 1

У меня была такая же проблема, когда элементы в recyclerview можно сфокусировать. Попробуйте следующее:

Опция 1 пользователь windowSoftInputMode = "adjustPan" в режиме прокрутки

Вариант 2 Добавьте свой настраиваемый ScrollListener к своему Activity, цель - когда RV начнет прокрутку, очистить текущий фокус.

protected class FocusableScrollListner implements OnScrollListener {

        @Override
        public void onScroll(AbsListView view, int firstVisibleItem,
                int visibleItemCount, int totalItemCount) {
            // do nothing 
        }

        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {
            if (SCROLL_STATE_TOUCH_SCROLL == scrollState) {
                View currentFocus = getCurrentFocus();
                if (currentFocus != null) {
                    currentFocus.clearFocus();
                }
            }
        }

    }

Вариант 3:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View currentFocus = ((Activity)context).getCurrentFocus();
    if (currentFocus != null) {
        currentFocus.clearFocus();
    }
}

в зависимости от вашего кода могут быть другие альтернативы, вам нужно убрать фокус.

конечно, я проверю это, ценю вашу помощь

DJphy 31.10.2018 20:50

Пожалуйста, дайте нам знать, помогло ли это, иначе, пожалуйста, поделитесь своими опасениями, постараемся разобраться.

aanshu 01.11.2018 06:58

попробовал ваше решение, не сработало, я не могу использовать вариант 2, так как моя платформа - телевизор, здесь сенсорный экран не работает, он работает с удаленной навигацией. также я не могу очистить фокус в obindviewholder, так как я зарегистрирован в onfocuschange

DJphy 02.11.2018 15:19

Другие вопросы по теме