web-dev-qa-db-fra.com

RecyclerView (horizontal) imbriqué dans BottomSheet empêchant le défilement vertical

J'ai un RecyclerView utilisant un LinearLayoutManager avec une orientation HORIZONTAL, imbriqué dans un FrameLayout en utilisant le BottomSheetBehavior.

Lorsque vous tentez de faire glisser verticalement sur le RecyclerView, le BottomSheet ne répond pas à l'événement de glissement. Cela est probablement dû au fait que le défilement vertical est désactivé pour un LayoutManager avec une orientation horizontale.

J'ai essayé de remplacer LinearLayoutManager.canScrollVertically() et de retourner true. Cette sorte de fonctionne. Si vous faites glisser verticalement de manière très prudente, le BottomSheet répondra. Cependant, dès qu'un mouvement horizontal est impliqué, le BottomSheet cesse de répondre aux événements de glissement vertical.

Je ne sais pas si remplacer canScrollVertically() est la bonne approche ici - cela ne semble certainement pas correct d'un point de vue UX.

J'ai également remarqué que si j'utilise un ViewPager plutôt qu'un RecyclerView avec un LayoutManager orienté horizontalement, le BottomSheet répond aux événements de balayage vertical comme souhaité .

Existe-t-il une autre méthode de LayoutManager, RecyclerView, BottomSheet Behavior, ou autre chose qui peut aider à propager les événements de défilement vertical sur le BottomSheet Behavior?

Il y a un exemple du problème ici:

https://github.com/timusus/bottomsheet-test (Le problème peut être reproduit avec commit # f59a7031)

Développez simplement la première feuille inférieure.

16
Tim Malseed

Où se situe le problème? Dans FrameLayout. BottomSheet fonctionne parfaitement lorsqu'il est placé à l'intérieur CoordinatorLayout. BottomSheet peut alors passer son état de défilement à travers CoordinatorLayout à d'autres vues mises en tant qu'enfants directs de CoordinatorLayout.

Pourquoi RecyclerView n'a pas pu passer l'état de défilement à BottomSheet? Ce n'est pas un enfant direct de CoordinatorLayout. Mais il existe un moyen de les passer: RecyclerView doit être mis en vue qui implémente NestedScrollingParent et NestedScrollingChild . La réponse à cela est: NestedScrollView

Vos mises en page fragment_sheetX.xml Devraient donc ressembler à:

<?xml version="1.0" encoding="utf-8"?>
<Android.support.v4.widget.NestedScrollView
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:background="#fff"
    Android:orientation="vertical"
    Android:fillViewport="true">

    <Android.support.v7.widget.RecyclerView
        Android:id="@+id/recyclerView"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"/>

</Android.support.v4.widget.NestedScrollView>

Notez également Android:fillViewport="true" Car sinon, votre RecyclerView ne prendra pas toute la hauteur.

Cependant, cela ne fonctionnera toujours pas. Pourquoi? RecyclerView doit être invité à passer le défilement vertical au parent. Comment? La réponse est recyclerView.setNestedScrollingEnabled(false);, mais c'est mieux décrit ici .

Btw: MultiSheetView est une excellente fonctionnalité et une approche très intéressante de la conception UX mobile.

28
R. Zagórski