Come disabilitare lo scorrimento di AppBarLayout in CoordinatorLayout?

Ho MapFragment con effetto di parallasse all’interno di AppBarLayout :

inserisci la descrizione dell'immagine qui

Voglio disabilitare lo scorrimento su AppBarLayout , perché non è ansible spostarsi su una mappa, dal momento che le note di touch sulla mappa vengono sempre gestite come eventi di scorrimento. Vorrei gestire il collasso di AppBarLayout scorrendo solo RecyclerView , che si trova nella parte inferiore dello schermo.

Questo è il mio xml:

  

             

Grazie per la risposta.

Non sono sicuro di averlo capito, ma penso che tu stia cercando una DragCallback .

L’interfaccia DragCallback consente di scegliere se la vista di scorrimento tra pari deve essere controllata da AppBarLayout su AppBarLayout .

Puoi definirne uno chiamando:

 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; } }); 

Restituendo sempre false , la visualizzazione a scorrimento non sarà più controllata da ABL.

Nota: prima di chiamare questo dovresti controllare che ViewCompat.isLaidOut(appBarLayout) , altrimenti params.getBehavior() restituirà null.

Problema

  1. AppBarLayout scorre anche se il contenuto di scorrimento si adatta allo schermo.
  2. È perché per impostazione predefinita possiamo trascinare AppBarLayout toccando e trascinando AppBarLayout.

Soluzione

  1. Disattiveremo il comportamento di “trascinamento” per AppBarLayout.

     // Disable "Drag" for AppBarLayout (ie 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); } 

Riferimento

  1. Questa è solo l’estensione della risposta accettata di “natario” sopra.

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

Quindi, dopo due ore di tentativi, ho trovato una soluzione, che è piuttosto semplice. Ho solo dovuto estendere CoordinatorLayout e sovrascrivere il metodo OnInterceptTouchEvent modo che la class assomigli a questo:

 public class NonTouchableCoordinatorLayout extends CoordinatorLayout { public NonTouchableCoordinatorLayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return false; } 

}

Puoi farlo definendo app:layout_behavior personalizzata app:layout_behavior in xml. Con questo approccio non devi preoccuparti di ottenere un riferimento a LayoutParams e di fare controlli nulli.

   

Quindi creare una class personalizzata che si estende da 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; } }); } } 

puoi usare NestedScrollView.setNestedScrollingEnabled(false) per disabilitare l’AppBarLayout nestScroll envent