with tutorial studio recyclerview example coordinatorlayout coordinator collapsing appbarlayout android android-coordinatorlayout android-collapsingtoolbarlayout supportmapfragment android-appbarlayout

android - tutorial - ¿Cómo deshabilitar el desplazamiento de AppBarLayout en CoordinatorLayout?



coordinatorlayout collapse (5)

Entonces, después de dos horas de intentarlo, he encontrado una solución, que es bastante simple. Solo necesitaba extender CoordinatorLayout y anular el método OnInterceptTouchEvent para que la clase se vea así:

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

}

Tengo MapFragment con efecto de paralaje dentro de AppBarLayout :

Quiero deshabilitar el desplazamiento en AppBarLayout , ya que no es posible desplazarse por el mapa, ya que las teclas de toque en el mapa siempre se manejan como eventos de desplazamiento. Me gustaría manejar el colapso de AppBarLayout desplazando RecyclerView solamente, que se encuentra en la parte inferior de la pantalla.

Este es mi 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" />

Gracias por la respuesta.


No estoy seguro de haberlo conseguido, pero creo que estás buscando un DragCallback .

La interfaz DragCallback permite elegir si la vista de desplazamiento de hermanos debe controlarse mediante los desplazamientos en AppBarLayout .

Puedes definir uno llamando al:

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

Al devolver siempre false , su vista de desplazamiento ya no será controlada por la ABL.

Nota: antes de llamar a esto, debe verificar que ViewCompat.isLaidOut(appBarLayout) , de lo contrario params.getBehavior() devolverá nulo.


Puedes lograr esto definiendo una app:layout_behavior personalizada app:layout_behavior en xml. Con este enfoque, no tiene que preocuparse por obtener una referencia a los LayoutParams y realizar comprobaciones nulas.

<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" >

Luego cree una clase personalizada que se extienda desde 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; } }); } }

Actualizado con la versión Kotlin:

class FixedAppBarLayoutBehavior(context: Context, attrs: AttributeSet) : AppBarLayout.Behavior(context, attrs) { init { setDragCallback(object : DragCallback() { override fun canDrag(appBarLayout: AppBarLayout): Boolean = false }) } }


puede usar el NestedScrollView.setNestedScrollingEnabled(false) para deshabilitar el entorno de anidación de la aplicación AppBarLayout


Problema

  1. AppBarLayout se desplaza incluso si el contenido de desplazamiento se ajusta a la pantalla.
  2. Esto se debe a que, de forma predeterminada, podemos arrastrar AppBarLayout tocando y arrastrando AppBarLayout.

Solución

  1. Deshabilitaremos el comportamiento de "Arrastrar" para 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); }

Referencia

  1. Esta es solo una extensión de la respuesta aceptada de "natario" arriba.

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