notifyitemremoved - Android: el elemento dentro de RecyclerView no se puede hacer clic después de desplazarse
remove all items recyclerview android (3)
Acabo de actualizar a la API 26 y la biblioteca de soporte 26.0.2. Pero descubrí que mis elementos RecyclerView
no se pueden hacer clic justo después del desplazamiento. Si esperas un segundo, funcionará. Pero si haces clic en el elemento inmediatamente, no lo hará. Incluso si RecyclerView
no se desplaza en absoluto (por ejemplo, se ha desplazado hacia la parte superior).
Cuando bajé de categoría para admitir la biblioteca 25.4.0, todo va bien de nuevo. El punto clave es que mi RecyclerView
está en un CoordinatorLayout
y tiene un indicador SCROLL_FLAG_SCROLL
en mi Toolbar
de Toolbar
de la AppBarLayout
. Si no uso esta bandera, este problema desaparecerá. Así que creo que es un cambio de comportamiento oculto de la biblioteca de soporte 26.
He intentado agregar focusable="false"
al CoordinatorLayout
pero aún no he tenido suerte.
¿Hay alguna manera de deshabilitar este comportamiento? Porque es realmente molesto hacer clic dos veces para activar el evento de clic.
<android.support.design.widget.CoordinatorLayout
android:id="@+id/coordinateLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="@+id/fragmentAppBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:elevation="0dp"
android:background="@null">
<include
android:id="@+id/dynamicActionBarHolder"
layout="@layout/dynamic_action_bar"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/pullToRefreshMailRecycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<android.support.v7.widget.RecyclerView
android:id="@+id/mailRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.v4.widget.SwipeRefreshLayout>
</android.support.design.widget.CoordinatorLayout>
EDITAR
Creo que el problema es el scrollState
de scrollState
de RecyclerView
. Cuando se detiene el desplazamiento, no se cambia a SCROLL_STATE_IDLE
inmediatamente. Al ViewFlinger
en el código fuente de RecyclerView
, descubrí que hay un ViewFlinger
controla el estado de desplazamiento. Cuando abro para desplazarme a la parte superior, no está llamando setScrollState(SCROLL_STATE_IDLE)
inmediato, sino que espera un tiempo para activar este método. Cuanto más rápido lanzo, más tiempo necesito esperar. Al igual que el RecyclerView todavía se está desplazando en el fondo. Debido a que scroller.isFinished()
no devuelve true justo después de que RecyclerView
deje de desplazarse cuando toca la parte superior. Tal vez sea un error de RecyclerView
cuando está en un CoordinatorLayout
.
Encontró una manera de forzar el estado de desplazamiento para estar inactivo. Esperando a google para solucionar este error.
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
boolean requestCancelDisallowInterceptTouchEvent = getScrollState() == SCROLL_STATE_SETTLING;
boolean consumed = super.onInterceptTouchEvent(event);
final int action = event.getActionMasked();
switch (action) {
case MotionEvent.ACTION_DOWN:
if( requestCancelDisallowInterceptTouchEvent ){
getParent().requestDisallowInterceptTouchEvent(false);
// only if it touched the top or the bottom. Thanks to @Sergey''s answer.
if (!canScrollVertically(-1) || !canScrollVertically(1)) {
// stop scroll to enable child view to get the touch event
stopScroll();
// do not consume the event
return false;
}
}
break;
}
return consumed;
}
EDITAR
El problema se ha solucionado en la biblioteca de soporte 27.0.1.
https://developer.android.com/topic/libraries/support-library/revisions.html#27-0-1
Después de que un usuario se desplaza, no pueden hacer clic en un elemento en un RecyclerView. (AOSP edición 66996774)
Actualizado el 17 de noviembre de 2017
Algunos usuarios informaron que este problema no se solucionó en la biblioteca de soporte 27.0.1. El rastreador de problemas está aquí. https://issuetracker.google.com/issues/66996774
Así que puedes elegir usar esta solución oficial. https://gist.github.com/chrisbanes/8391b5adb9ee42180893300850ed02f2
O usa este aquí.
He encontrado un código fuente que resolvió este problema. Este problema ocurre debido al comportamiento de AppBarLayout (AppBarLayout.Behavior). Este código fuente proporciona un comportamiento extendido o de personalización del comportamiento de AppBarLayout y lo establece en AppBarLayout con introducción de uso tanto en XML como directamente en Java. Solo puedo explicarlo brevemente porque la fuente tiene licencia, por lo que también debe leerlo. Consulte la solución en este enlace: https://gist.github.com/chrisbanes/8391b5adb9ee42180893300850ed02f2
Muchas gracias por esta pregunta y su respuesta! Me ahorró mucho tiempo. Lo siento por publicar esto como una respuesta. No tengo suficiente reputación para comentar.
También noté este problema, pero como nuevo desarrollador de Android no me di cuenta de que era un error dentro de la nueva biblioteca de soporte.
Lo que quería sugerir es también agregar este cheque:
if( requestCancelDisallowInterceptTouchEvent ){
if (!canScrollVertically(-1) || !canScrollVertically(1)) {
...
}
}
Se asegurará de que mientras se recorre RecyclerView, no hagamos clic en ningún elemento.
Según tengo entendido, es un comportamiento esperado. Sin embargo, su respuesta me ayudó con esta question .