Necesita deshabilitar expandir CollapsingToolbarLayout para ciertos fragmentos

Tengo AppCompatActivity que controla el reemplazo de muchos fragmentos. Aquí está mi diseño para eso.

activity_main.xml

    

activity_main_frame.xml

              

El fragmento de mi inicio está configurado inicialmente y es allí donde quiero que la barra de herramientas contraída se expanda y que funcione bien. Sin embargo, cuando cambio fragmentos de un cajón lateral, quiero desactivar la barra de herramientas desplegable.

He descubierto cómo colapsarlo cuando se selecciona un elemento de un cajón, pero también necesito asegurarme de que no se expanda a menos que se muestre el fragmento de inicio. ¿es posible?

 public void collapseToolbar(){ CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) appbar.getLayoutParams(); behavior = (AppBarLayout.Behavior) params.getBehavior(); if(behavior!=null) { behavior.onNestedFling(coordinator, appbar, null, 0, 10000, true); } } 

    Ahora, en v23 de la biblioteca de soporte, puede controlar fácilmente la visibilidad de su barra de aplicaciones.

    Simplemente haga una referencia a su AppBarLayout y escúpela / muéstrela según el fragmento que quiera cargar:

     private AppBarLayout appBarLayout; @Override protected void onCreate(Bundle savedInstanceState) { [...] appBarLayout = (AppBarLayout) findViewById(R.id.appbar); [...] } public void switchToFragment(Fragment fragment, String tag, boolean expandToolbar){ FragmentManager fragmentManager = getSupportFragmentManager(); Fragment currentFragment = fragmentManager.findFragmentByTag(currentFragmentTag); if(currentFragment == null || !TextUtils.equals(tag, currentFragmentTag) ){ currentFragmentTag = tag; fragmentManager .beginTransaction() .replace(R.id.flContent, fragment, currentFragmentTag) .commit(); if(expandToolbar){ appBarLayout.setExpanded(true,true); }else{ appBarLayout.setExpanded(false,true); } } } 

    PD: no olvide agregar las dependencias requeridas en su build.gradle:

     dependencies { compile 'com.android.support:design:23.2.1' compile 'com.android.support:appcompat-v7:23.2.1' compile 'com.android.support:recyclerview-v7:23.2.1' } 

    EDITAR: Si también desea bloquear su barra de herramientas en ciertos fragmentos (además del colapso), debe recurrir a soluciones provisionales, ya que esta característica no es proporcionada por CollapsingToolbarLayout hasta ahora (v23.2.1 del diseño de soporte). Aquí puede encontrar mi solución alternativa propuesta.

    Inhabilita el desplazamiento nested en el contenido del fragmento desplazable:

     recyclerView.setNestedScrollingEnabled(false); 

    Use esto si está usando la biblioteca de soporte:

     ViewCompat.setNestedScrollingEnabled(recyclerView, false); 

    Esta clase le permitirá desactivar / volver a habilitar el comportamiento de expansión.

     public class DisableableAppBarLayoutBehavior extends AppBarLayout.Behavior { private boolean mEnabled; public DisableableAppBarLayoutBehavior() { super(); } public DisableableAppBarLayoutBehavior(Context context, AttributeSet attrs) { super(context, attrs); } public void setEnabled(boolean enabled) { mEnabled = enabled; } @Override public boolean onStartNestedScroll(CoordinatorLayout parent, AppBarLayout child, View directTargetChild, View target, int nestedScrollAxes) { return mEnabled && super.onStartNestedScroll(parent, child, directTargetChild, target, nestedScrollAxes); } public boolean isEnabled() { return mEnabled; } } 

    Úselo en su diseño así:

        

    Luego, cuando quiera deshabilitar el comportamiento:

     AppBarLayout myAppBar = ....; CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) myAppBar.getLayoutParams(); ((DisableableAppBarLayoutBehavior) layoutParams.getBehavior()).setEnabled(false); 

    Todo lo que tiene que hacer es reemplazar CoordinatorLayout con una implementación personalizada de CoordinatorLayout que engañará que se haya manejado el desplazamiento nested.

    Implementación de MyCoordinatorLayout:

     public class MyCoordinatorLayout extends CoordinatorLayout { private boolean allowForScroll = false; public MyCoordinatorLayout(Context context) { super(context); } public MyCoordinatorLayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) { return allowForScroll && super.onStartNestedScroll(child, target, nestedScrollAxes); } public boolean isAllowForScroll() { return allowForScroll; } public void setAllowForScroll(boolean allowForScroll) { this.allowForScroll = allowForScroll; } } 

    vista de actividad xml:

                     

    Lo invito a utilizar la implementación personalizada de AppBarLayout con métodos de ayuda para contraer / expandir la barra de herramientas. En este sentido , puedes encontrar uno.

    Ok, ahora es el momento de configurar nuestra barra de herramientas en actividad.

     public class ToolbarAppcompatActivity extends AppCompatActivity implements AppBarLayout.OnOffsetChangedListener { protected Toolbar toolbar; protected MyCoordinatorLayout coordinator; protected ControllableAppBarLayout appbar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); configureToolbar(); switchFragment(new FooFragment(), "FOO", true); } protected void configureToolbar() { toolbar = (Toolbar) findViewById(R.id.toolbar); coordinator = (MyCoordinatorLayout) findViewById(R.id.coordinator); appbar = (ControllableAppBarLayout) findViewById(R.id.appbar); appbar.addOnOffsetChangedListener(this); getDelegate().setSupportActionBar(toolbar); } public void switchToFragment(Fragment fragment, String tag, boolean expandToolbar){ FragmentManager fragmentManager = getSupportFragmentManager(); Fragment currentFragment = fragmentManager.findFragmentByTag(currentFragmentTag); if(currentFragment == null || !TextUtils.equals(tag, currentFragmentTag) ){ currentFragmentTag = tag; fragmentManager .beginTransaction() .replace(R.id.flContent, fragment, currentFragmentTag) .commit(); if(expandToolbar){ expandToolbar(); }else{ collapseToolbar(); } } } protected void addFragment(Fragment fragment, String tag, boolean expandToolbar) { FragmentManager fragmentManager = getSupportFragmentManager(); currentFragmentTag = tag; fragmentManager .beginTransaction() .add(R.id.flContent, fragment, currentFragmentTag) .addToBackStack(tag) .commit(); if(expandToolbar){ expandToolbar(); }else{ collapseToolbar(); } } protected void collapseToolbar(){ appbar.collapseToolbar(); coordinator.setAllowForScroll(false); } public void expandToolbar(){ appbar.expandToolbar(); coordinator.setAllowForScroll(true); } } 

    Cada vez que desee cambiar la barra de herramientas fragmentar y colapsar / expandir, simplemente llame al método switchFragment / addFragment con el parámetro booleano adecuado.

    Solo una última nota. Asegúrese de usar las últimas bibliotecas de soporte.

     dependencies { // android support compile 'com.android.support:appcompat-v7:22.2.1' compile 'com.android.support:recyclerview-v7:22.2.1' compile 'com.android.support:design:22.2.1' } 

    No use la etiqueta de inclusión en AppBarLayout. No funciona

    Con Android Design Library v23.1.1, el método descrito por @LucyFair no funciona. Me las arreglé para que funcione al configurar la app:layout_scrollFlags para enterAlwaysCollapsed solo a enterAlwaysCollapsed , y la barra de aplicaciones permanece “bloqueada”.

    Espero que esto ayude. 🙂

    Encontré una solución simple para habilitar / deshabilitar el colapso en CollapsingToolbarLayout:

      private void setExpandEnabled(boolean enabled) { mAppBarLayout.setExpanded(enabled, false); mAppBarLayout.setActivated(enabled); final AppBarLayout.LayoutParams params = (AppBarLayout.LayoutParams) collapsingToolbarLayout.getLayoutParams(); if (enabled) params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED); else params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS | AppBarLayout.LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED); collapsingToolbarLayout.setLayoutParams(params); } 

    He encontrado una solución alternativa que funciona con actividad y varios fragmentos. Implementa el CollapsingToolbarLayout con AppBar, etc. en su actividad y luego cada vez que llama a un nuevo fragmento puede llamar a estas 2 funciones.

    • Cuando quiero que mi barra de aplicaciones se mantenga contraída:

       public void lockAppBarClosed() { mAppBarLayout.setExpanded(false, false); mAppBarLayout.setActivated(false); CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams)mAppBarLayout.getLayoutParams(); lp.height = (int) getResources().getDimension(R.dimen.toolbar_height); } 
    • Cuando quiero que mi barra de aplicaciones se expanda y se vuelva a desplazar

       public void unlockAppBarOpen() { mAppBarLayout.setExpanded(true, false); mAppBarLayout.setActivated(true); CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams)mAppBarLayout.getLayoutParams(); lp.height = (int) getResources().getDimension(R.dimen.toolbar_expand_height); } 

    Puede invocar estas funciones desde sus fragmentos implementando una interfaz. Aquí hay un ejemplo rápido para su caso (la barra de herramientas se expande solo en homeFragment)

     public interface CustomListener() { void unlockAppBarOpen(); void lockAppBarClosed() } public class MainActivity extends BaseActivity implements CustomListener { @Override public void unlockAppBarOpen() { mAppBarLayout.setExpanded(true, false); mAppBarLayout.setActivated(true); CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams)mAppBarLayout.getLayoutParams(); lp.height = (int) getResources().getDimension(R.dimen.toolbar_expand_height); } @Override public void lockAppBarClosed() { mAppBarLayout.setExpanded(false, false); mAppBarLayout.setActivated(false); CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams)mAppBarLayout.getLayoutParams(); lp.height = (int) getResources().getDimension(R.dimen.toolbar_height); } } public class MainFragment extends BaseFragment { @Override public void onResume() { super.onPause(); ((MainActivity) getContext()).unlockAppBarOpen(); } } public class SecondFragment extends BaseFragment { @Override public void onResume() { super.onPause(); ((MainActivity) getContext()).lockAppBarClosed(); } } 

    Con este ejemplo:

    • cada vez que se muestre MainFragment -> extenderá la barra de herramientas y la hará extensible y expandible

    • cada vez que se muestra SecondFragment -> il colapsará la barra de herramientas a un tamaño estándar y evitará que se expanda nuevamente

    Espero que te ayude !

    He utilizado la solución de DragCallback y DragCallback añadido DragCallback a la clase de comportamiento para evitar tocar y arrastrar CollapsingToolbarLayout para expandirlo

     private void setDragCallback() { setDragCallback(new DragCallback() { @Override public boolean canDrag(@NonNull AppBarLayout appBarLayout) { return mEnabled; } }); } 

    No puedo hacer ningún comentario, por lo tanto, publicaré mis adiciones a la solución DisableWay AdaptabyBarLayoutBehavior de JasonWyatt como respuesta independiente.

     public class DisableableAppBarLayoutBehavior extends AppBarLayout.Behavior { private boolean mEnabled = true; // enabled by default public DisableableAppBarLayoutBehavior() { super(); } public DisableableAppBarLayoutBehavior(Context context, AttributeSet attrs) { super(context, attrs); } public void setEnabled(boolean enabled) { mEnabled = enabled; } @Override public boolean onStartNestedScroll(CoordinatorLayout parent, AppBarLayout child, View directTargetChild, View target, int nestedScrollAxes, int type) { return mEnabled && super.onStartNestedScroll(parent, child, directTargetChild, target, nestedScrollAxes, type); } @Override public void onNestedScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int type) { if (!isEnabled()) return; super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type); } @Override public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, int dx, int dy, int[] consumed, int type) { if (!isEnabled()) return; super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type); } public boolean isEnabled() { return mEnabled; } } 

    Además de onStartNestedScroll, también se bloquea en NestedPreScroll y onNestedScroll para evitar comportamientos inesperados. Por ejemplo, en mi caso, al llamar a setExpanded (falso, verdadero) en la barra de mi aplicación se frenó el comportamiento esperado y aún se expandía con retrasos. Ahora funciona:

     LayoutParams layoutParams = (LayoutParams) context.appBarLayout.getLayoutParams(); ((DisableableAppBarLayoutBehavior)layoutParams.getBehavior()).setEnabled(false); context.appBarLayout.setLayoutParams(layoutParams); context.appBarLayout.setExpanded(false, true); // collapse app bar 

    Ninguna de las soluciones proporcionadas funcionó para mí excepto esta. Con esta solución, puedo administrar fácilmente el estado de la barra de herramientas colapsada. Esto evitará la expansión de la barra de herramientas contraer y establecer el título para ella.

     public void lockAppBar(boolean locked,String title) { if(locked){ appBarLayout.setExpanded(false, true); int px = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 80, getResources().getDisplayMetrics()); CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams)appBarLayout.getLayoutParams(); lp.height = px; appBarLayout.setLayoutParams(lp); collapsingToolbarLayout.setTitleEnabled(false); toolbar.setTitle(title); }else{ appBarLayout.setExpanded(true, false); appBarLayout.setActivated(true); CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams(); lp.height = (int) getResources().getDimension(R.dimen.toolbarExpandHeight); collapsingToolbarLayout.setTitleEnabled(true); collapsingToolbarLayout.setTitle(title); } } 

    Puede bloquear la expansión de la barra de herramientas de la aplicación restableciendo la altura de la barra de herramientas de colapsar a la altura de la barra de herramientas

     toolbarHeight = toolbar.getLayoutParams().height; if (expand) { collapsingToolbar.getLayoutParams().height = getResources().getDimensionPixelOffset(R.dimen.collapsingToolbarDefaultHeight); appBarLayout.setExpanded(true, true); } else { //collapse //** it is important you do this before resetting ** appBarLayout.setExpanded(false, true); appBarLayout.postDelayed(new Runnable() { @Override public void run() { collapsingToolbar.getLayoutParams().height = toolbarHeight; } }, 700/* 600 is default animation time to collapse */); } 

    Encuentre la id de AppBarLayout como esta.

     appBarLayout = (AppBarLayout) findViewById(R.id.appbar); 

    Deshabilitar expandir CollapsingToolbarLayout para ciertos fragmentos

     appBarLayout.setExpanded(true,true); 

    Habilitar expandir CollapsingToolbarLayout para ciertos fragmentos

     appBarLayout.setExpanded(false,true); 

    Espero que te ayude !!

    El siguiente código logra 3 objectives:

    Inhabilite CollapsingToolbarLayout expandir o colapsar por el usuario, pero aún así permitir AppBarLayout.setExpanded .

    Evite el desplazamiento de RecyclerView o NestedScrollView de expandir o contraer el CollapsingToolbarLayout.

     // scrollView can be RecyclerView or NestedScrollView ViewCompat.setNestedScrollingEnabled(scrollView, false) 

    Evite que el usuario expanda o contraiga CollapsingToolbarLayout al presionar la barra de herramientas.

     val params = appBar.layoutParams as CoordinatorLayout.LayoutParams if (params.behavior == null) params.behavior = AppBarLayout.Behavior() val behaviour = params.behavior as AppBarLayout.Behavior behaviour.setDragCallback(object : AppBarLayout.Behavior.DragCallback() { override fun canDrag(appBarLayout: AppBarLayout): Boolean { return false } }) 

    https://code.luasoftware.com/tutorials/android/how-to-disable-or-lock-collapsingtoolbarlayout-collapse-or-expand/