макетирование:
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, я предоставляю ссылку на диск для того же. Код макета адаптера и просмотрщика
спасибо, проверил их, к сожалению, не имеет отношения ко мне.
Не могу помочь только с трассировкой стека, прикрепленной к вопросу.
@hardartcore Я добавлю код адаптера и код макета просмотрщика, так ли?
Попробуйте это: your_scrollview_object.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
@ Ümañg ßürmån спасибо, все та же ошибка
Не могли бы вы приложить снимок экрана к проблеме. и меня больше беспокоит ваш комментарий «Авария происходит, скажем, если меньше строк (например, 4).» - Хотел просмотреть пользовательский интерфейс.
@jiteshmohite, пожалуйста, проверьте добавленные скриншоты
@DJphy: ReclerView содержит только четыре элемента на втором снимке экрана?
@jiteshmohite да, любое количество строк меньше вертикальной длины экрана, при попытке прокрутки с использованием фокуса происходит сбой, отлично работает, если присутствует большее количество элементов (строк)
@DJphy Я не уверен, поможет ли это, но вам следует без промедления связать представления в onBindViewHolder, потому что именно тогда RecyclerView выполняет обновления своих представлений впоследствии. Я подозреваю, что если вы привяжете свои представления к Handler.postDelayed, ваша привязка может не работать или столкнуться с неожиданным поведением. Поэтому попробуйте удалить блок задержки, и вам, вероятно, придется найти другой способ асинхронной загрузки данных.
У меня была такая же проблема, когда элементы в 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();
}
}
в зависимости от вашего кода могут быть другие альтернативы, вам нужно убрать фокус.
конечно, я проверю это, ценю вашу помощь
Пожалуйста, дайте нам знать, помогло ли это, иначе, пожалуйста, поделитесь своими опасениями, постараемся разобраться.
попробовал ваше решение, не сработало, я не могу использовать вариант 2, так как моя платформа - телевизор, здесь сенсорный экран не работает, он работает с удаленной навигацией. также я не могу очистить фокус в obindviewholder, так как я зарегистрирован в onfocuschange
Вы можете выложить свой код, адаптер вы написали