Je viens de passer à l'API 26 et à la bibliothèque de support 26.0.2. Mais j’ai trouvé que mes éléments RecyclerView
ne sont pas cliquables juste après le défilement. Si vous attendez une seconde, cela fonctionnera. Mais si vous cliquez immédiatement sur l'élément, il ne le fera pas. Même si la RecyclerView
ne défile pas du tout (par exemple, a fait défiler vers le haut).
Lorsque j'ai rétrogradé pour prendre en charge la bibliothèque 25.4.0, tout va bien à nouveau ... Le point clé est que ma RecyclerView
est dans une CoordinatorLayout
et a un drapeau SCROLL_FLAG_SCROLL
sur ma Toolbar
de la AppBarLayout
. Si je n'utilise pas ce drapeau, ce problème disparaîtra. Donc, je pense que c'est un changement de comportement caché de la bibliothèque de support 26.
J'ai essayé d'ajouter focusable="false"
à la CoordinatorLayout
mais je n'ai toujours pas eu de chance.
Est-il possible de désactiver ce comportement? Parce que c'est vraiment ennuyant de cliquer deux fois pour déclencher l'événement click.
<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>
MODIFIER
Je pense que le problème est la scrollState
de la RecyclerView
. Lorsque le défilement est arrêté, il n'est pas immédiatement remplacé par SCROLL_STATE_IDLE
. En regardant dans le code source de RecyclerView
, j'ai trouvé qu'il y avait une ViewFlinger
contrôlant l'état de défilement. Lorsque je descends pour faire défiler vers le haut, il n'appelle pas setScrollState(SCROLL_STATE_IDLE)
immédiatement, il attend un certain temps pour déclencher cette méthode. Plus je lance vite, plus je dois attendre. Tout comme le RecyclerView défile toujours en arrière-plan. Parce que la scroller.isFinished()
ne retourne pas vrai juste après la RecyclerView
, arrêtez de faire défiler la liste lorsqu'elle touche le haut. Peut-être que c'est un bug de la RecyclerView
quand c'est dans une CoordinatorLayout
.
Nous avons trouvé un moyen de forcer l'état de défilement à être inactif . Nous attendons que Google corrige ce bogue.
@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;
}
MODIFIER
Le problème a été corrigé dans la bibliothèque de support 27.0.1.
https://developer.Android.com/topic/libraries/support-library/revisions.html#27-0-1
Une fois qu'un utilisateur a fait défiler, il ne peut plus cliquer sur un élément de RecyclerView. (Numéro AOSP 66996774)
Mis à jour le 17 nov. 2017
Certains utilisateurs ont signalé que ce problème n'était pas résolu dans la bibliothèque de support technique 27.0.1 . Le suivi du problème est ici . https://issuetracker.google.com/issues/66996774
Vous pouvez donc utiliser cette solution de contournement officielle . https://Gist.github.com/chrisbanes/8391b5adb9ee42180893300850ed02f2
Ou utilisez celui-ci ici.
Merci beaucoup pour cette question et votre réponse! Cela m'a fait gagner beaucoup de temps. Désolé de poster ceci comme une réponse. Je n'ai pas assez de réputation pour commenter.
J'ai également remarqué ce problème, mais en tant que nouveau développeur Android, je n'avais pas réalisé que c'était un bogue dans la nouvelle bibliothèque de support.
Ce que je voulais suggérer, c'est aussi d'ajouter ce chèque:
if( requestCancelDisallowInterceptTouchEvent ){
if (!canScrollVertically(-1) || !canScrollVertically(1)) {
...
}
}
Cela fera en sorte que pendant le défilement de RecyclerView, nous ne cliquons sur aucun élément.
Si je comprends bien, c'est un comportement attendu. Cependant, votre réponse m'a aidé avec cette question .
J'ai trouvé un code source qui a résolu ce problème. Ce problème est dû au comportement de AppBarLayout (AppBarLayout.Behavior). Ce code source fournit un comportement de comportement d'extension ou de personnalisation d'AppBarLayout et le définit dans AppBarLayout avec l'introduction de l'utilisation à la fois directement en XML ou en Java. Je ne peux expliquer que brièvement parce que la source a une licence qui oblige à la lire aussi. Veuillez voir la solution dans ce lien: https://Gist.github.com/chrisbanes/8391b5adb9ee42180893300850ed02f2