studio - toolbar guidelines android




É necessário desativar a expansão no CollapsingToolbarLayout para determinados fragmentos (9)

Agora, na v23 da biblioteca de suporte, você pode controlar facilmente a visibilidade da barra de aplicativos.

Basta obter uma referência ao seu AppBarLayout e ocultar / mostrar, dependendo do fragmento que você deseja carregar:

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

O PS não se esqueça de adicionar as dependências necessárias no seu 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' 
}

Edição: Se você também deseja bloquear sua barra de ferramentas em certos fragmentos (além do recolhimento), é necessário recorrer a soluções alternativas, pois esse recurso não é fornecido pelo CollapsingToolbarLayout até agora (v23.2.1 do design de suporte). Here você pode encontrar minha solução alternativa proposta.

Eu tenho um AppCompatActivity que controla a substituição de muitos fragmentos. Aqui está o meu layout para isso.

activity_main.xml

<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:fitsSystemWindows="true">

<include layout="@layout/activity_main_frame"/>

<android.support.design.widget.NavigationView
    android:id="@+id/navigation_view"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:fitsSystemWindows="true"
    android:background="@color/white"
    app:headerLayout="@layout/drawer_header"
    app:menu="@menu/drawer"/>

</android.support.v4.widget.DrawerLayout>

activity_main_frame.xml

<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

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

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            android:fitsSystemWindows="true"
            app:contentScrim="?attr/colorPrimary"
            app:expandedTitleMarginStart="48dp"
            app:expandedTitleMarginEnd="64dp">

            <ImageView
                android:id="@+id/backdrop"
                android:layout_width="match_parent"
                android:layout_height="256dp"
                android:scaleType="centerCrop"
                android:fitsSystemWindows="true"
                app:layout_collapseMode="parallax" />

            <include layout="@layout/activity_main_items"/>

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                app:layout_collapseMode="pin"/>

            <android.support.design.widget.TabLayout
                android:id="@+id/tabs"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:visibility="gone"
                android:layout_gravity="bottom"/>

        </android.support.design.widget.CollapsingToolbarLayout>

    </android.support.design.widget.AppBarLayout>

    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" >
    </FrameLayout>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab1"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        app:layout_anchor="@id/appbar"
        app:layout_anchorGravity="bottom|right|end"
        app:borderWidth="0dp"
        android:src="@drawable/app_ic_slide_wallpaper_dark"
        android:layout_margin="@dimen/big_padding"
        android:clickable="true"/>

</android.support.design.widget.CoordinatorLayout>

Meu fragmento inicial é definido inicialmente e é aí que eu quero a barra de ferramentas recolhida expandida e que funciona bem. No entanto, quando troco fragmentos da gaveta lateral, quero desativar a barra de ferramentas em expansão.

Eu descobri como recolhê-lo quando um item da gaveta é selecionado, mas também preciso garantir que ele não se expanda, a menos que o fragmento inicial seja exibido. Isso é possível?

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

Com a Android Design Library v23.1.1, o método descrito por @LucyFair não funciona. Consegui fazê-lo funcionar, definindo o app:layout_scrollFlags para enterAlwaysCollapsed apenas, e a barra de aplicativos permanece "bloqueada".

Espero que isto ajude. :)


Desative a rolagem aninhada no conteúdo do fragmento de rolagem:

recyclerView.setNestedScrollingEnabled(false);

Use isso se você estiver usando a biblioteca de suporte:

ViewCompat.setNestedScrollingEnabled(recyclerView, false);

Encontrei Solução simples para ativar / desativar o recolhimento em 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);
    }

Eu encontrei uma solução alternativa que funciona com atividade e vários fragmentos. Você implementa o CollapsingToolbarLayout com AppBar etc em sua atividade e, a cada vez que chama um novo fragmento, pode chamar essas 2 funções.

  • Quando eu quero que minha barra de aplicativos seja recolhida:

    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);
    }
  • Quando quero que minha barra de aplicativos seja expandida e rolada novamente

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

Você pode chamar essas funções de seus fragmentos implementando uma interface. Aqui está um exemplo rápido, para o seu caso (a barra de ferramentas se expande apenas em 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();
    }
}

Com este exemplo:

  • sempre que o MainFragment for exibido -> ele estenderá a barra de ferramentas e a tornará dobrável e expansível

  • cada vez que o SecondFragment é exibido -> il reduz a barra de ferramentas para um tamanho padrão e evita que ela se expanda novamente

Espero que ajude você!


Eu usei a solução de DragCallback e adicionei o DragCallback à classe de comportamento para impedir o toque e o arraste CollapsingToolbarLayout para expandi-lo

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

O código a seguir atinge três objetivos:

Desative a expansão ou recolhimento do CollapsingToolbarLayout pelo usuário, mas ainda permita o AppBarLayout.setExpanded .

Impedir a rolagem do RecyclerView ou NestedScrollView de expandir ou recolher o CollapsingToolbarLayout.

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

Impeça o usuário de expandir ou recolher o CollapsingToolbarLayout passando rapidamente o AppBar.

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/


Tudo o que você precisa fazer é substituir o CoordinatorLayout pela implementação personalizada do CoordinatorLayout, que enganará a manipulação da rolagem aninhada.

Implementação do 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;
    }
}

xml da visualização da atividade:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >

    <android.support.v4.widget.DrawerLayout
        android:id="@+id/drawerLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >

        <!--CONTENT-->

        <com.example.views.MyCoordinatorLayout
            android:id="@+id/coordinator"
            xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:app="http://schemas.android.com/apk/res-auto"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true"
            >

        <com.example.views.ControllableAppBarLayout
            android:id="@+id/appbar"
            android:layout_width="match_parent"
            android:layout_height="192dp"
            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="match_parent"
                android:fitsSystemWindows="true"
                app:contentScrim="?attr/colorPrimary"
                app:expandedTitleMarginBottom="32dp"
                app:expandedTitleMarginEnd="64dp"
                app:expandedTitleMarginStart="48dp"
                app:layout_scrollFlags="scroll|exitUntilCollapsed">

                <ImageView
                    android:id="@+id/header"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:background="@color/primary"
                    android:fitsSystemWindows="true"
                    android:scaleType="centerCrop"
                    app:layout_collapseMode="parallax" />

                <android.support.v7.widget.Toolbar
                    android:id="@+id/toolbar"
                    android:layout_width="match_parent"
                    android:layout_height="?attr/actionBarSize"
                    app:layout_collapseMode="pin"
                    app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

            </android.support.design.widget.CollapsingToolbarLayout>

        </com.example.views.ControllableAppBarLayout>

        <FrameLayout
            android:id="@+id/flContent"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            />

        </com.example.views.MyCoordinatorLayout>


        <!-- DRAWER -->

        <fragment
            android:id="@+id/fDrawer"
            android:name="com.example.fragment.DrawerFragment"
            android:layout_width="@dimen/drawer_width"
            android:layout_height="match_parent"
            android:layout_gravity="left|start"
            android:fitsSystemWindows="true"
            android:clickable="true"
            />

    </android.support.v4.widget.DrawerLayout>

</LinearLayout>

Convido você a usar a implementação AppBarLayout personalizada com métodos auxiliares para recolher / expandir a barra de ferramentas. Nesta gist você pode encontrar um.

Ok, agora é hora de configurar nossa barra de ferramentas em atividade.

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

}

Toda vez que você desejar alternar fragmentos e recolher / expandir a barra de ferramentas, chame o método switchFragment / addFragment com o parâmetro booleano adequado.

Apenas uma última nota. Certifique-se de usar as bibliotecas de suporte mais recentes.

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'

}

Não use a tag include no AppBarLayout. Não funciona


Encontre o ID do AppBarLayout como este.

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

Desativar a expansão no CollapsingToolbarLayout para determinados fragmentos

appBarLayout.setExpanded(true,true);

Ative a expansão no CollapsingToolbarLayout para determinados fragmentos

appBarLayout.setExpanded(false,true);

Espero que ajude você !!







coordinator-layout