Como uso o DrawerLayout para exibir sobre a ActionBar / Barra de Ferramentas e sob a barra de status?

394

Eu vi no novo design de material Side Nav Spec que você pode exibir a gaveta sobre a barra de ação e atrás da barra de status. Como posso implementar isso?

Chris Banes
fonte
4
Ainda hoje não há uma resposta clara que funcione com compatibilidade com versões anteriores. Esse tipo de problema realmente irrita qualquer programador. Já está promovendo a API "N" e muitos aspectos básicos para melhorar o sistema Android.
Val Martinez

Respostas:

528

Novas funcionalidades na estrutura e nas bibliotecas de suporte permitem exatamente isso. Existem três 'peças do quebra-cabeça':

  1. Usando a Barra de ferramentas para que você possa incorporar sua barra de ação à sua hierarquia de visualizações.
  2. Fazendo DrawerLayout fitsSystemWindows para que seja colocado atrás das barras do sistema.
  3. Desativar Theme.Materiala coloração normal da barra de status para que DrawerLayout possa desenhar lá.

Presumo que você usará o novo appcompat.

Primeiro, seu layout deve ficar assim:

<!-- The important thing to note here is the added fitSystemWindows -->
<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/my_drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <!-- Your normal content view -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <!-- We use a Toolbar so that our drawer can be displayed
             in front of the action bar -->
        <android.support.v7.widget.Toolbar  
            android:id="@+id/my_awesome_toolbar"
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:minHeight="?attr/actionBarSize"
            android:background="?attr/colorPrimary" />

        <!-- The rest of your content view -->

    </LinearLayout>

    <!-- Your drawer view. This can be any view, LinearLayout
         is just an example. As we have set fitSystemWindows=true
         this will be displayed under the status bar. -->
    <LinearLayout
        android:layout_width="304dp"
        android:layout_height="match_parent"
        android:layout_gravity="left|start"
        android:fitsSystemWindows="true">

        <!-- Your drawer content -->

    </LinearLayout>

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

Então em sua Atividade / Fragmento:

public void onCreate(Bundled savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Your normal setup. Blah blah ...

    // As we're using a Toolbar, we should retrieve it and set it
    // to be our ActionBar
    Toolbar toolbar = (...) findViewById(R.id.my_awesome_toolbar);
    setSupportActionBar(toolbar);

    // Now retrieve the DrawerLayout so that we can set the status bar color.
    // This only takes effect on Lollipop, or when using translucentStatusBar
    // on KitKat.
    DrawerLayout drawerLayout = (...) findViewById(R.id.my_drawer_layout);
    drawerLayout.setStatusBarBackgroundColor(yourChosenColor);
}

Então você precisa garantir que o DrawerLayout esteja visível atrás da barra de status. Você faz isso alterando o tema values-v21:

values-v21 / themes.xml

<style name="Theme.MyApp" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowDrawsSystemBarBackgrounds">true</item>
    <item name="android:statusBarColor">@android:color/transparent</item>
    <item name="android:windowTranslucentStatus">true</item>
</style>

Nota: Se a <fragment android:name="fragments.NavigationDrawerFragment">é usado em vez de

<LinearLayout
    android:layout_width="304dp"
    android:layout_height="match_parent"
    android:layout_gravity="left|start"
    android:fitsSystemWindows="true">

    <!-- Your drawer content -->

</LinearLayout>

No layout real, o efeito desejado será alcançado se você chamar fitsSystemWindows(boolean)uma exibição que retorne do onCreateViewmétodo.

@Override
public View onCreateView(LayoutInflater inflater, 
                         ViewGroup container,
                         Bundle savedInstanceState) {
    View mDrawerListView = inflater.inflate(
        R.layout.fragment_navigation_drawer, container, false);
    mDrawerListView.setFitsSystemWindows(true);
    return mDrawerListView;
}
Chris Banes
fonte
3
Sim, DrawerLayouté necessário que ele seja colocado atrás das barras do sistema. Você precisa configurá-lo na vista da gaveta para que DrawerLayoutele fique dentro das inserções da janela.
precisa
11
Não consigo fazer isso funcionar. Com o código acima em um novo aplicativo de demonstração, o resultado é semelhante ao que o @ScootrNova descreve. Veja esta captura de
Michael Schmidt
6
Parece que você realmente precisa usar um negativo layout_marginTopna raiz do layout do conteúdo da gaveta. Caso contrário, o plano de fundo do layout do conteúdo da gaveta será desenhado na parte superior da barra de status e todo o resto será pressionado. No entanto, isso parece ser uma solução meio grosseira, tanto quanto eu sei que não há? Attr / statusBarSize ou algo parecido com o fornecido pelo Android.
Charles Madere
26
Para obter o efeito em que a gaveta é visível através da barra de status, acabei definindo android: fitsSystemWindows para false no DrawerLayout, android: fitsSystemWindows para true no meu layout de conteúdo principal (o layout que contém a Barra de Ferramentas) e adicionando <nome do item = "android: windowTranslucentStatus"> true </ item> para o meu tema - no Lollipop que é
Jakob
8
Esta resposta está incompleta. Você também precisa quebrar sua gaveta de navegação dentro de um ScrimLayout. Veja stackoverflow.com/a/26926998/174149
Markus Hi
138

EDIT: A nova Biblioteca de Suporte de Design suporta isso e o método anterior não é mais necessário.

Agora isso pode ser conseguido usando a nova Biblioteca de Suporte de Design Android .

Você pode ver o aplicativo de exemplo Cheesesquare de Chris Banes, que demonstra todos os novos recursos.


Método anterior:

Como não há uma solução completa postada, eis o modo como atingi o resultado desejado.

Primeiro, inclua um ScrimInsetsFrameLayout no seu projeto.

/*
* Copyright 2014 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* A layout that draws something in the insets passed to 
* {@link #fitSystemWindows(Rect)}, i.e. the area above UI chrome
* (status and navigation bars, overlay action bars).
*/
public class ScrimInsetsFrameLayout extends FrameLayout {
    private Drawable mInsetForeground;

    private Rect mInsets;
    private Rect mTempRect = new Rect();
    private OnInsetsCallback mOnInsetsCallback;

    public ScrimInsetsFrameLayout(Context context) {
        super(context);
        init(context, null, 0);
    }

    public ScrimInsetsFrameLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs, 0);
    }

    public ScrimInsetsFrameLayout(
        Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context, attrs, defStyle);
    }

    private void init(Context context, AttributeSet attrs, int defStyle) {
        final TypedArray a = context.obtainStyledAttributes(attrs,
                R.styleable.ScrimInsetsView, defStyle, 0);
        if (a == null) {
            return;
        }
        mInsetForeground = a.getDrawable(
            R.styleable.ScrimInsetsView_insetForeground);
        a.recycle();

        setWillNotDraw(true);
    }

    @Override
    protected boolean fitSystemWindows(Rect insets) {
        mInsets = new Rect(insets);
        setWillNotDraw(mInsetForeground == null);
        ViewCompat.postInvalidateOnAnimation(this);
        if (mOnInsetsCallback != null) {
            mOnInsetsCallback.onInsetsChanged(insets);
        }
        return true; // consume insets
    }

    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);

        int width = getWidth();
        int height = getHeight();
        if (mInsets != null && mInsetForeground != null) {
            int sc = canvas.save();
            canvas.translate(getScrollX(), getScrollY());

            // Top
            mTempRect.set(0, 0, width, mInsets.top);
            mInsetForeground.setBounds(mTempRect);
            mInsetForeground.draw(canvas);

            // Bottom
            mTempRect.set(0, height - mInsets.bottom, width, height);
            mInsetForeground.setBounds(mTempRect);
            mInsetForeground.draw(canvas);

            // Left
            mTempRect.set(
                0, 
                mInsets.top, 
                mInsets.left, 
                height - mInsets.bottom);
            mInsetForeground.setBounds(mTempRect);
            mInsetForeground.draw(canvas);

            // Right
            mTempRect.set(
                width - mInsets.right, 
                mInsets.top, width, 
                height - mInsets.bottom);
            mInsetForeground.setBounds(mTempRect);
            mInsetForeground.draw(canvas);

            canvas.restoreToCount(sc);
        }
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        if (mInsetForeground != null) {
            mInsetForeground.setCallback(this);
        }
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if (mInsetForeground != null) {
            mInsetForeground.setCallback(null);
        }
    }

    /**
     * Allows the calling container to specify a callback for custom 
     * processing when insets change (i.e. when {@link #fitSystemWindows(Rect)}
     * is called. This is useful for setting padding on UI elements 
     * based on UI chrome insets (e.g. a Google Map or a ListView). 
     * When using with ListView or GridView, remember to set
     * clipToPadding to false.
     */
    public void setOnInsetsCallback(OnInsetsCallback onInsetsCallback) {
        mOnInsetsCallback = onInsetsCallback;
    }

    public static interface OnInsetsCallback {
        public void onInsetsChanged(Rect insets);
    }
}

Em seguida, crie um estilo para que insetForegroundpossa ser definido.

values ​​/ attrs.xml

<declare-styleable name="ScrimInsetsView">
    <attr name="insetForeground" format="reference|color" />
</declare-styleable>

Atualize o arquivo xml da sua atividade e verifique se android:fitsSystemWindowsestá definido como true tanto no DrawerLayoutquanto no ScrimInsetsFrameLayout.

layout / activity_main.xml

<android.support.v4.widget.DrawerLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawerLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context=".MainActivity">

    <!-- The main content view -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <!-- Your main content -->

    </LinearLayout>

    <!-- The navigation drawer -->
    <com.example.app.util.ScrimInsetsFrameLayout 
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/scrimInsetsFrameLayout"
        android:layout_width="320dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:background="@color/white"
        android:elevation="10dp"
        android:fitsSystemWindows="true"
        app:insetForeground="#4000">

        <!-- Your drawer content -->

    </com.example.app.util.ScrimInsetsFrameLayout>

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

Dentro do método onCreate da sua atividade, defina a cor de fundo da barra de status no layout da gaveta.

MainActivity.java

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // ...

    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout);
    mDrawerLayout.setStatusBarBackgroundColor(
        getResources().getColor(R.color.primary_dark));
}

Por fim, atualize o tema do seu aplicativo para que DrawerLayoutfique atrás da barra de status.

values-v21 / styles.xml

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowDrawsSystemBarBackgrounds">true</item>
    <item name="android:statusBarColor">@android:color/transparent</item>
</style>

Resultado:

Suyash
fonte
10
Isso funcionou melhor para mim. Passei 2 dias para fazer essa coisa funcionar e essa é a única. Isso deve ser marcado como resposta. Muito obrigado.
kalehv
2
Não estou usando appcompat e isso não funcionou. :( Existe algum guia de obter este trabalho sem appcompat?
Jared Rummler
3
Esta é a resposta mais perfeita. Eu o implementei e testei em vários dispositivos Android do 4.X ao 5.X e posso confirmar que ele funciona perfeitamente. Muito obrigado.
Aritra Roy
2
Como eu disse, funciona perfeitamente, mas tenho um pequeno problema. A atividade com a Gaveta de Navegação possui a barra de status transparente, mas todas as outras atividades perderam a cor "primaryDark" da barra de status. Como recuperar isso?
Aritra Roy
5
Levei três dias para aceitar que atualmente não há outra maneira senão usar esse layout adicional enrolado no fragmento da gaveta. Caso contrário, a barra de status será cinza (cor de fundo da primeira criança) ou a gaveta será exibida abaixo da barra de status.
precisa
96

Com o lançamento da mais recente Biblioteca de suporte Android (rev 22.2.0) , temos uma Biblioteca de suporte a design e, como parte disso, uma nova exibição chamada NavigationView . Então, em vez de fazer tudo por conta própria com ScrimInsetsFrameLayouttodas as outras coisas, simplesmente usamos essa visão e tudo é feito por nós.

Exemplo

Passo 1

Adicione o Design Support Libraryao seu build.gradlearquivo

dependencies {
    // Other dependencies like appcompat
    compile 'com.android.support:design:22.2.0'
}

Passo 2

Adicione NavigationViewao seu DrawerLayout:

<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_width="match_parent"
     android:layout_height="match_parent"
     android:fitsSystemWindows="true"> <!-- this is important -->

     <!-- Your contents -->

     <android.support.design.widget.NavigationView
         android:id="@+id/navigation"
         android:layout_width="wrap_content"
         android:layout_height="match_parent"
         android:layout_gravity="start"
         app:menu="@menu/navigation_items" /> <!-- The items to display -->
 </android.support.v4.widget.DrawerLayout>

etapa 3

Crie um novo recurso de menu /res/menue adicione os itens e ícones que deseja exibir:

<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <group android:checkableBehavior="single">
        <item
            android:id="@+id/nav_home"
            android:icon="@drawable/ic_action_home"
            android:title="Home" />
        <item
            android:id="@+id/nav_example_item_1"
            android:icon="@drawable/ic_action_dashboard"
            android:title="Example Item #1" />
    </group>

    <item android:title="Sub items">
        <menu>
            <item
                android:id="@+id/nav_example_sub_item_1"
                android:title="Example Sub Item #1" />
        </menu>
    </item>

</menu>

Passo 4

Inicie o NavigationView e manipule eventos de clique:

public class MainActivity extends AppCompatActivity {

    NavigationView mNavigationView;
    DrawerLayout mDrawerLayout;

    // Other stuff

    private void init() {
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mNavigationView = (NavigationView) findViewById(R.id.navigation_view);
        mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(MenuItem menuItem) {
                mDrawerLayout.closeDrawers();
                menuItem.setChecked(true);
                switch (menuItem.getItemId()) {
                    case R.id.nav_home:
                        // TODO - Do something
                        break;
                    // TODO - Handle other items
                }
                return true;
            }
        });
    }
}

Etapa 5

Certifique-se de definir android:windowDrawsSystemBarBackgroundse android:statusBarColor, values-v21caso contrário, sua gaveta não será exibida "sob" a Barra de Status

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Other attributes like colorPrimary, colorAccent etc. -->
    <item name="android:windowDrawsSystemBarBackgrounds">true</item>
    <item name="android:statusBarColor">@android:color/transparent</item>
</style>

Etapa opcional

Adicione um cabeçalho ao NavigationView. Para isso, basta criar um novo layout e adicionar app:headerLayout="@layout/my_header_layout"ao NavigationView.

Resultado

imagem mostrando a visualização de navegação

Notas

  • A cor destacada usa a cor definida pelo colorPrimaryatributo
  • Os itens da lista usam a cor definida pelo textColorPrimaryatributo
  • Os ícones usam a cor definida através do textColorSecondaryatributo

Você também pode verificar o aplicativo de exemplo de Chris Banes, que destaca o NavigationView junto com os outros novos modos de exibição que fazem parte da Biblioteca de suporte de design (como FloatingActionButton , TextInputLayout , Snackbar , TabLayout etc.)

reverter
fonte
11
obrigado @reVerse !!. > Se você quiser atualizar todos os itens e ícones da lista a partir dos arquivos de estilo, poderá fazê-lo usando:<item name="itemTextColor">@color/YOUR_COLOR</item> <item name="itemIconTint">@color/YOUR_COLOR</item>
Juan Saravia
Como você altera a cor de fundo do item selecionado?
26415 Joop
2
Essa abordagem ainda produz o NavigationView que está por trás do ActionBar.
Southerton
11
@southerton é claro, você tem que usar um Toolbar- não há nenhuma maneira de fazer isso com umActionBar
reverso
11
@ reegan29 Basta ligar para mDrawerLayout.openDrawer(GravityCompat.START);onde quiser. Se você estiver usando um, ActionBarDrawerToggleisso deve ser feito automaticamente assim que você clicar no ícone do hambúrguer.
reverso
6

Faça com que funcione, nos estilos values-v21 ou no tema xml precisa usar este atributo:

<item name="android:windowTranslucentStatus">true</item>

Isso faz a mágica!

Nicolas Jafelle
fonte
3
Isso faz com que minha barra de ação apareça atrás da barra de status também.
5134 Michiel #
Mas esse é o efeito que estamos tentando alcançar, veja o aplicativo Gmail 5.0? Ele mostra a barra lateral atrás da barra de status.
Nicolas Jafelle
Não é isso que eu quis dizer. Mesmo que a gaveta de navegação esteja atrás da barra de status com esta linha de código, o mesmo ocorre com a barra de ferramentas / barra de ação.
Michiel
2
O pôster e a resposta é um funcionário do Google que criou o AppCompat, por isso tenho certeza de que ele sabia o que estava fazendo quando escreveu o conteúdo.
170014 afollestad
@ Mixx, você pode definir o android: fitsSystemWindows = "true" para a visualização normal do conteúdo (se utilizado o layout de resposta aceito, por exemplo). Pode funcionar, mesmo para o Android 4.4. Mas há uma pequena diferença aqui: no Android 5.0, o nível de transparência na barra de status é um pouco maior (valor alfa mais alto) do que no GMail, tornando a barra de status ainda mais escura.
Qianqian
6

As abordagens acima estão corretas e podem estar funcionando. Eu criei uma demonstração de trabalho seguindo o guia acima e testei em 2.x a 5.x

Você pode clonar no Github

O importante é brincar na Atividade Principal

toolbar = (Toolbar) findViewById(R.id.toolbar);
res = this.getResources();

this.setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 
    ScrimInsetsFrameLayout scrimInsetsFrameLayout = (ScrimInsetsFrameLayout)
            findViewById(R.id.linearLayout);
    scrimInsetsFrameLayout.setOnInsetsCallback(this);
} 

e a ligação de volta

@Override
public void onInsetsChanged(Rect insets) {
    Toolbar toolbar = this.toolbar;
    ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams)
        toolbar.getLayoutParams();
    lp.topMargin = insets.top;
    int top = insets.top;
    insets.top += toolbar.getHeight();
    toolbar.setLayoutParams(lp);
    insets.top = top; // revert
}

Absolutamente o Tema para V21 faz a mágica

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- API 21 theme customizations can go here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/accent_material_light</item>
    <item name="windowActionModeOverlay">true</item>
    <item name="android:windowDrawsSystemBarBackgrounds">true</item>
    <item name="android:statusBarColor">@android:color/transparent</item>
    <item name="android:windowTranslucentStatus">true</item>
</style>

e o ScrimInsetsFrameLayout

Agora isso ficou mais fácil com a nova biblioteca de Design Design

compile 'com.android.support:design:22.2.0'

clone de @Chris Banes https://github.com/chrisbanes/cheesesquare

Vipin Sahu
fonte
4

Todas as respostas mencionadas aqui são muito antigas e demoradas. A melhor e mais curta solução que funciona com o Navigationview mais recente é

@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
    super.onDrawerSlide(drawerView, slideOffset);

    try {
        //int currentapiVersion = android.os.Build.VERSION.SDK_INT;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP){
            // Do something for lollipop and above versions

        Window window = getWindow();

        // clear FLAG_TRANSLUCENT_STATUS flag:
        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

        // add FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS flag to the window
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);

        // finally change the color to any color with transparency

         window.setStatusBarColor(getResources().getColor(R.color.colorPrimaryDarktrans));}

    } catch (Exception e) {

        Crashlytics.logException(e);

    }
}

isso mudará a cor da barra de status para transparente quando você abrir a gaveta

Agora, quando você fechar a gaveta, precisará alterar novamente a cor da barra de status para escuro.

        public void onDrawerClosed(View drawerView) {
        super.onDrawerClosed(drawerView);
        try {
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP){
    // Do something for lollipop and above versions

    Window window = getWindow();

    // clear FLAG_TRANSLUCENT_STATUS flag:
    window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

    // add FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS flag to the window
    window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);

    // finally change the color again to dark
    window.setStatusBarColor(getResources().getColor(R.color.colorPrimaryDark));}
    } catch (Exception e) {
    Crashlytics.logException(e);
                    }
                    }

e, em seguida, no layout principal, adicione uma única linha, ou seja,

            android:fitsSystemWindows="true"

e o layout da sua gaveta será semelhante

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

e sua visualização de navegação será semelhante

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

Se você está procurando por uma solução para o seu problema, entre em contato com o suporte técnico da Microsoft para obter mais informações. Marque-o se isso ajudar.

Harry Sharma
fonte
Como alternativa, se você estiver usando uma exibição personalizada no ActionBar, poderá definir a visibilidade da exibição personalizada como INVISÍVEL em onDrawerSlide () e VISÍVEL em onDrawerClosed ().
Milão
3

Estou usando a Biblioteca de suporte de design. E apenas usando o tema personalizado, obtive a Barra de status transparente ao abrir a gaveta de navegação.

insira a descrição da imagem aqui

insira a descrição da imagem aqui

<style name="NavigationStyle" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/primaryColor</item>
    <item name="colorPrimaryDark">@color/primaryColorDark</item>

    <!-- To Make Navigation Drawer Fill Status Bar and become Transparent Too -->
    <item name="android:windowDrawsSystemBarBackgrounds">true</item>
    <item name="android:statusBarColor">@android:color/transparent</item>

</style>

Por fim, adicione o tema no arquivo de manifesto

<activity
  ........
  ........
 android:theme="@style/NavigationStyle"> 
</activity>

Não se esqueça de usar a propriedade, android:fitsSystemWindows="true"em "DrawerLayout"

Katwal-Dipak
fonte
11
como usar isso para dispositivos de nível 19 da API?
AndroidGuy
2

Este é o mais simples e funcionou para mim:

Nos valores-21:

<resources>
    <style name="AppTheme" parent="AppTheme.Base">
        ...
        <item name="android:windowTranslucentStatus">true</item>
    </style>
    <dimen name="topMargin">25dp</dimen>
</resources>

Nos valores:

<resources>
    <dimen name="topMargin">0dp</dimen>
</resources>

E defina na sua barra de ferramentas

android:layout_marginTop="@dimen/topMargin"
Nicolás López
fonte
Eu também fiz isso, e funcionou como um encanto no Lollipop. Mas eu usei 24dppara a margem superior.
19415 Rafa
Quando você divide a tela em dispositivos com Android 7.1, pode ver essa lacuna na parte superior se o aplicativo for a segunda parte da tela.
Cícero Moura
1

Em vez de usar o ScrimInsetsFrameLayout... Não é mais fácil adicionar apenas uma exibição com uma altura fixa 24dpe um plano de fundo primaryColor?

Entendo que isso envolve adicionar uma visão fictícia na hierarquia, mas me parece mais limpo.

Eu já tentei e está funcionando bem.

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_base_drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <!-- THIS IS THE VIEW I'M TALKING ABOUT... -->
        <View
            android:layout_width="match_parent"
            android:layout_height="24dp"
            android:background="?attr/colorPrimary" />

        <android.support.v7.widget.Toolbar
            android:id="@+id/activity_base_toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:elevation="2dp"
            android:theme="@style/ThemeOverlay.AppCompat.Dark" />

        <FrameLayout
            android:id="@+id/activity_base_content_frame_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    </LinearLayout>

    <fragment
        android:id="@+id/activity_base_drawer_fragment"
        android:name="com.myapp.drawer.ui.DrawerFragment"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:elevation="4dp"
        tools:layout="@layout/fragment_drawer" />

</android.support.v4.widget.DrawerLayout>
mato
fonte
Quando você divide a tela em dispositivos com Android 7.1, pode ver essa lacuna na parte superior se o aplicativo for a segunda parte da tela.
Cícero Moura
0

Tente com isto:

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


<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!--Main layout and ads-->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <FrameLayout
            android:id="@+id/ll_main_hero"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1">

        </FrameLayout>

        <FrameLayout
            android:id="@+id/ll_ads"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <View
                android:layout_width="320dp"
                android:layout_height="50dp"
                android:layout_gravity="center"
                android:background="#ff00ff" />
        </FrameLayout>


    </LinearLayout>

    <!--Toolbar-->
    <android.support.v7.widget.Toolbar
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/toolbar"
        android:elevation="4dp" />
</FrameLayout>


<!--left-->
<ListView
    android:layout_width="240dp"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:choiceMode="singleChoice"
    android:divider="@null"
    android:background="@mipmap/layer_image"
    android:id="@+id/left_drawer"></ListView>

<!--right-->
<FrameLayout
    android:layout_width="240dp"
    android:layout_height="match_parent"
    android:layout_gravity="right"
    android:background="@mipmap/layer_image">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@mipmap/ken2"
        android:scaleType="centerCrop" />
</FrameLayout>

estilo :

<style name="ts_theme_overlay" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorPrimary">@color/red_A700</item>
    <item name="colorPrimaryDark">@color/red1</item>
    <item name="android:windowBackground">@color/blue_A400</item>
</style>

Atividade principal estende ActionBarActivity

toolBar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolBar);

Agora você pode onCreateOptionsMenu gostar da ActionBar normal com a ToolBar.

Este é o meu layout

  • PARTE SUPERIOR: Gaveta esquerda - Gaveta direita
    • MID: Barra de ferramentas (ActionBar)
    • INFERIOR: ListFragment

Espero que você entenda, divirta-se!

Filho Nguyen Thanh
fonte