14

Je MapFragment avec effet de parallaxe à l'intérieur AppBarLayout:Comment désactiver le défilement de AppBarLayout dans CoordinatorLayout?

enter image description here

Je veux désactiver le défilement sur AppBarLayout, car il est impossible de se déplacer à travers la carte, depuis evenys touch sur la carte sont toujours traités comme défilement des événements . Je voudrais gérer l'effondrement de AppBarLayout en faisant défiler RecyclerView seulement, qui est sur le bas de l'écran.

Ceci est mon xml:

<?xml version="1.0" encoding="utf-8"?> 

<android.support.design.widget.AppBarLayout 
    android:id="@+id/appbar" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:fitsSystemWindows="true" 
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> 

    <android.support.design.widget.CollapsingToolbarLayout 
     android:id="@+id/collapsing_toolbar" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:fitsSystemWindows="true" 
     app:contentScrim="@color/white" 
     app:expandedTitleMarginEnd="64dp" 
     app:expandedTitleMarginStart="48dp" 
     app:layout_scrollFlags="scroll|exitUntilCollapsed|snap" 
     app:titleEnabled="false"> 

     <FrameLayout 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      app:layout_collapseMode="parallax" 
      android:fitsSystemWindows="true"> 

      <fragment 
       android:id="@+id/map" 
       android:name="com.androidmapsextensions.SupportMapFragment" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" /> 
     </FrameLayout> 

     <android.support.v7.widget.Toolbar 
      android:id="@+id/toolbar" 
      android:layout_width="match_parent" 
      android:layout_height="73dp" 
      app:contentInsetLeft="0dp" 
      app:contentInsetStart="0dp" 
      app:layout_collapseMode="pin" 
      app:popupTheme="@style/ThemeOverlay.AppCompat.Light"> 

      <include 
       android:id="@+id/search_bar" 
       layout="@layout/layout_searchbar" /> 
     </android.support.v7.widget.Toolbar> 

     <View 
      android:id="@+id/toolbar_shadow" 
      android:layout_width="match_parent" 
      android:layout_height="3dp" 
      android:layout_below="@id/search_bar" 
      android:layout_gravity="bottom" 
      android:background="@drawable/toolbar_dropshadow" 
      android:visibility="gone" /> 
    </android.support.design.widget.CollapsingToolbarLayout> 
</android.support.design.widget.AppBarLayout> 


<RecyclerView 
    android:id="@+id/farm_list" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="@android:color/transparent" 
    app:layout_behavior="@string/appbar_scrolling_view_behavior" /> 

Merci pour la réponse.

+0

Où est votre 'CoordinatorLayout'? –

Répondre

35

Je ne suis pas sûr que je l'ai eu, mais je pense que vous êtes à la recherche d'un DragCallback.

L'interface DragCallback permet de choisir si la vue de défilement de la fratrie doit être contrôlée par défilement sur AppBarLayout.

Vous pouvez définir un en appelant:

CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams(); 
AppBarLayout.Behavior behavior = (AppBarLayout.Behavior) params.getBehavior(); 
behavior.setDragCallback(new AppBarLayout.Behavior.DragCallback() { 
    @Override 
    public boolean canDrag(@NonNull AppBarLayout appBarLayout) { 
     return false; 
    } 
}); 

En revenant toujours false, votre point de vue de défilement ne sera pas contrôlé par l'ABL plus longtemps.

Remarque: avant d'appeler cela, vous devez vérifier que ViewCompat.isLaidOut(appBarLayout), sinon params.getBehavior() renverra null.

+0

En fait, la solution que j'ai ajouté ci-dessus a fait l'affaire, mais je vous remercie de l'aide de toute façon. Je suis curieux donc je vais l'essayer :) – janox1x2x3

+1

La définition d'un événement InteractTouchEvent au coordinateur pourrait vous poser problème à l'avenir. C'est la solution "officielle" (si j'ai votre question). – natario

+1

Impossible de le faire fonctionner avec cette solution. Pouvez-vous expliquer un peu plus, s'il vous plaît? Merci –

3

Donc, après deux heures d'essai, j'ai trouvé une solution, ce qui est assez simple. J'ai juste besoin d'étendre CoordinatorLayout et remplacer la méthode OnInterceptTouchEvent si la classe ressemble à ceci:

public class NonTouchableCoordinatorLayout extends CoordinatorLayout { 
public NonTouchableCoordinatorLayout(Context context, AttributeSet attrs) { 
    super(context, attrs); 
} 

@Override 
public boolean onInterceptTouchEvent(MotionEvent ev) { 
    return false; 
} 

}

+1

il désactiver élargir, mais pas désactiver effondrement .. –

17

Problème

  1. défile AppBarLayout même si le contenu de défilement de l'écran. Adapte C'est parce que nous pouvons par défaut faire glisser AppBarLayout en touchant & en faisant glisser AppBarLayout.

Solution

  1. Nous désactivons "Faire glisser" pour le comportement AppBarLayout.

    // Disable "Drag" for AppBarLayout (i.e. User can't scroll appBarLayout by directly touching appBarLayout - User can only scroll appBarLayout by only using scrollContent) 
    if (appBarLayout.getLayoutParams() != null) { 
        CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams(); 
        AppBarLayout.Behavior appBarLayoutBehaviour = new AppBarLayout.Behavior(); 
        appBarLayoutBehaviour.setDragCallback(new AppBarLayout.Behavior.DragCallback() { 
         @Override 
         public boolean canDrag(@NonNull AppBarLayout appBarLayout) { 
          return false; 
         } 
        }); 
        layoutParams.setBehavior(appBarLayoutBehaviour); 
    } 
    

Référence

  1. Ceci est juste l'extension de la réponse acceptée "de Natario" ci-dessus.

  2. https://developer.android.com/reference/android/support/design/widget/AppBarLayout.Behavior.DragCallback.html

+0

Homme parfait! Je vous remercie! – anthony

+0

Salut Vasanth! Je veux désactiver le défilement d'utilisateur (de CoordinatorLayout) quand il défile dans le recyclerview. comment puis-je faire ça s'il vous plait? – anthony

3

Vous pouvez accomplir cela en définissant une coutume app:layout_behavior en XML. Avec cette approche, vous n'avez pas à vous soucier d'obtenir une référence au LayoutParams et de faire des vérifications nuls.

<android.support.design.widget.AppBarLayout 
     android:id="@+id/app_bar_layout" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     app:layout_behavior="com.yourcompany.FixedAppBarLayoutBehavior" 
     > 

Ensuite, créez une classe personnalisée qui s'étend de AppBarLayout.Behavior.

public class FixedAppBarLayoutBehavior extends AppBarLayout.Behavior { 

    public FixedAppBarLayoutBehavior(Context context, AttributeSet attrs) { 
    super(context, attrs); 

    setDragCallback(new DragCallback() { 
     @Override public boolean canDrag(@NonNull AppBarLayout appBarLayout) { 
     return false; 
     } 
    }); 
    } 
} 
+0

Ceci est la bonne solution –

0

vous pouvez utiliser le NestedScrollView.setNestedScrollingEnabled(false) pour désactiver le AppBarLayout nestScroll envent