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.

Solutions Collecting From Web of "Come disabilitare lo scorrimento di AppBarLayout in CoordinatorLayout?"

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