Come posso utilizzare DrawerLayout per visualizzare su ActionBar / Toolbar e sotto la barra di stato?


394

Ho visto nel nuovo design del materiale le specifiche di Side Nav che puoi visualizzare il cassetto sopra la barra delle azioni e dietro la barra di stato. Come posso implementarlo?


4
Ancora oggi non esiste una risposta chiara che funzioni con la compatibilità con le versioni precedenti. Questo tipo di problemi esaspera davvero qualsiasi programmatore. Promuovendo già l'API "N" e molti aspetti di base per migliorare il sistema Android.
Val Martinez,

Risposte:


528

Le nuove funzionalità nel framework e le librerie di supporto lo consentono esattamente. Esistono tre "pezzi del puzzle":

  1. Utilizzare la barra degli strumenti in modo da poter incorporare la barra delle azioni nella gerarchia della vista.
  2. Realizzazione di DrawerLayout in fitsSystemWindows modo che sia disposto dietro le barre di sistema.
  3. Disabilitando Theme.Materialla normale colorazione della barra di stato in modo che DrawerLayout possa disegnare lì.

Presumo che utilizzerai la nuova appcompat.

Innanzitutto, il layout dovrebbe essere simile al seguente:

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

Quindi nella tua attività / frammento:

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

Quindi devi assicurarti che DrawerLayout sia visibile dietro la barra di stato. Lo fai cambiando il tema valori-v21:

Valori-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 <fragment android:name="fragments.NavigationDrawerFragment">si utilizza a anziché

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

    <!-- Your drawer content -->

</LinearLayout>

il layout effettivo, l'effetto desiderato sarà raggiunto se si richiama fitsSystemWindows(boolean)una vista che si ritorna dal onCreateViewmetodo.

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

3
Sì, è DrawerLayoutnecessario che sia disposto dietro le barre di sistema. È quindi necessario impostarlo sulla vista del cassetto in modo che DrawerLayoutsia disposto all'interno delle finestre.
Chris Banes,

11
Non riesco a farlo funzionare affatto. Con il codice sopra riportato in una nuova applicazione demo, il risultato è simile a quello descritto da @ScootrNova. Vedi questa schermata: imgur.com/QLk3syt
Michael Schmidt,

6
Sembra che tu debba effettivamente usare un negativo layout_marginTopnella radice del layout del contenuto del tuo cassetto. Altrimenti, lo sfondo del layout del contenuto del tuo cassetto verrà disegnato sulla parte superiore della barra di stato e tutto il resto verrà spostato verso il basso. Questa tuttavia sembra una soluzione grossolana, per quanto ne so non esiste? Attr / statusBarSize o qualcosa del genere fornito da Android.
Charles Madere,

26
Per ottenere l'effetto in cui il cassetto è visibile attraverso la barra di stato, ho finito per impostare android: fitsSystemWindows su false su DrawerLayout, android: fitsSystemWindows su true sul mio layout di contenuto principale (il layout contenente la barra degli strumenti) e aggiungendo <nome elemento = "android: windowTranslucentStatus"> true </item> al mio tema - su Lollipop ovvero
Jakob

8
Questa risposta è incompleta. Devi anche avvolgere il tuo cassetto di navigazione all'interno di uno ScrimLayout. Vedi stackoverflow.com/a/26926998/174149
Markus Ciao

138

EDIT: la nuova libreria di supporto alla progettazione supporta questo e il metodo precedente non è più necessario.

Ciò può ora essere ottenuto utilizzando la nuova libreria di supporto di progettazione Android .

Puoi vedere l' app di esempio Cheesesquare di Chris Banes che mostra tutte le nuove funzionalità.


Metodo precedente:

Dal momento che non è stata pubblicata una soluzione completa, ecco il modo in cui ho raggiunto il risultato desiderato.

Per prima cosa includi uno ScrimInsetsFrameLayout nel tuo progetto.

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

Quindi crea uno stile in modo che insetForegroundpossa essere impostato.

Valori / attrs.xml

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

Aggiornare il file XML di vostra attività e assicurarsi android:fitsSystemWindowsè impostata su true sia sul DrawerLayoutcosì come il 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>

All'interno del metodo onCreate della tua attività imposta il colore di sfondo della barra di stato sul layout del cassetto.

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

Infine, aggiorna il tema della tua app in modo che DrawerLayoutsia dietro la barra di stato.

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

Risultato:


10
Questo ha funzionato al meglio per me. Ho trascorso 2 giorni per far funzionare questa cosa e questa è quella. Questo dovrebbe essere contrassegnato come risposta. Grazie mille.
kalehv,

2
Non sto usando Appcompat e questo non ha funzionato. :( Esiste una guida per farlo funzionare senza appcompat?
Jared Rummler

3
Questa è la risposta più perfetta L'ho implementato e testato su vari dispositivi Android da 4.X a 5.X e posso confermare che funziona perfettamente. Molte grazie.
Aritra Roy,

2
Come ho detto, funziona perfettamente, ma ho un piccolo problema. L'attività con il cassetto di navigazione ha la barra di stato trasparente, ma tutte le altre attività hanno perso il colore "primaryDark" dalla barra di stato. Come riaverlo?
Aritra Roy,

5
Mi ci sono voluti tre giorni per accettare che attualmente non c'è altro modo che utilizzare questo layout aggiuntivo avvolto attorno al frammento del cassetto. Altrimenti la barra di stato sarà grigia (colore di sfondo del primo figlio) o il cassetto verrà visualizzato sotto la barra di stato.
Denis Loh,

96

Con il rilascio dell'ultima libreria di supporto per Android (rev 22.2.0) abbiamo una libreria di supporto per il design e come parte di essa una nuova vista chiamata NavigationView . Quindi, invece di fare tutto da soli con ScrimInsetsFrameLayouttutte le altre cose, usiamo semplicemente questa vista e tutto è fatto per noi.

Esempio

Passo 1

Aggiungi il Design Support Libraryal tuo build.gradlefile

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

Passo 2

Aggiungi il NavigationViewal tuo 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>

Passaggio 3

Crea una nuova risorsa menu /res/menue aggiungi gli elementi e le icone che vuoi visualizzare:

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

Passaggio 4

Iniziare NavigationView e gestire gli eventi clic:

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

Passaggio 5

Assicurarsi di impostare android:windowDrawsSystemBarBackgroundse android:statusBarColorin values-v21caso contrario il vostro cassetto non potrà essere sostituita visualizzato "sotto" la StatusBar

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

Passaggio opzionale

Aggiungi un'intestazione a NavigationView. Per questo è sufficiente creare un nuovo layout e aggiungerlo app:headerLayout="@layout/my_header_layout"a NavigationView.

Risultato

immagine che mostra la vista di navigazione

Appunti

  • Il colore evidenziato utilizza il colore definito tramite l' colorPrimaryattributo
  • Le voci dell'elenco utilizzano il colore definito tramite l' textColorPrimaryattributo
  • Le icone usano il colore definito tramite l' textColorSecondaryattributo

Puoi anche controllare l' app di esempio di Chris Banes che evidenzia NavigationView insieme alle altre nuove viste che fanno parte della libreria di supporto del design (come FloatingActionButton , TextInputLayout , Snackbar , TabLayout ecc.)


1
grazie @reVerse !!. > Se vuoi aggiornare ogni elemento e icona nell'elenco dai file di stile, puoi farlo usando:<item name="itemTextColor">@color/YOUR_COLOR</item> <item name="itemIconTint">@color/YOUR_COLOR</item>
Juan Saravia,

Come si cambia il colore di sfondo dell'elemento selezionato?
Joop,

2
Questo approccio produce ancora NavigationView che si trova dietro ActionBar.
southerton,

1
@southerton ovviamente, devi usare un Toolbar- non c'è modo di farlo con unActionBar
reVerse

1
@ reegan29 Chiama semplicemente mDrawerLayout.openDrawer(GravityCompat.START);dove vuoi. Se lo stai usando, ActionBarDrawerTogglequesto dovrebbe essere fatto automaticamente non appena fai clic sull'icona dell'hamburger.
ripetere il

6

Fallo funzionare, negli stili valori-v21 o nel tema xml devi usare questo attributo:

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

Questo rende la magia!


3
Questo fa apparire la mia barra delle azioni anche dietro la barra di stato.
Michiel,

Ma questo è l'effetto che stiamo cercando di ottenere, guarda l'app di Gmail 5.0? Mostra la barra laterale dietro la barra di stato.
Nicolas Jafelle,

Non intendevo dire questo. Anche se il riquadro di navigazione si trova dietro la barra di stato con questa riga di codice, così come la barra degli strumenti / barra delle azioni.
Michiel,

2
Il mittente e il risponditore sono un dipendente di Google che ha progettato AppCompat, quindi sono abbastanza sicuro che sapesse cosa stava facendo quando ha scritto il contenuto.
afollestad,

@Mixx, È possibile impostare android: fitsSystemWindows = "true" per la normale visualizzazione del contenuto (se preso il layout di risposta accettato, ad esempio). Può funzionare, anche per Android 4.4. Ma c'è una leggera differenza qui: in Android 5.0 il livello di trasparenza sulla barra di stato è leggermente più alto (valore alfa più alto) rispetto a quello di GMail, rendendo la barra di stato ancora più scura.
Qianqian,

6

Soprattutto gli approcci sono corretti e potrebbero funzionare. Ho creato una demo funzionante seguendo la guida sopra e testato da 2.x a 5.x

Puoi clonare da Github

La cosa importante da giocare è nell'attività principale

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 la richiamata

@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
}

Assolutamente il tema per V21 fa la magia

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

Ora questo diventa più semplice con la nuova libreria di supporto alla progettazione

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

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


4

Tutte le risposte menzionate qui sono troppo vecchie e lunghe. La soluzione migliore e breve che funziona con la più recente navigazione è

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

    }
}

questo cambierà il colore della barra di stato in trasparente quando si apre il cassetto

Ora quando chiudi il cassetto devi cambiare di nuovo il colore della barra di stato in scuro, quindi puoi farlo in questo modo.

        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 quindi nel layout principale aggiungere una sola riga, ad es

            android:fitsSystemWindows="true"

e il layout del tuo cassetto sarà simile

            <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 apparirà la tua vista di navigazione

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

L'ho testato e funziona perfettamente. Spero che aiuti qualcuno. Questo potrebbe non essere l'approccio migliore ma funziona senza problemi ed è semplice da implementare. Contrassegna se aiuta. Codifica felice :)


In alternativa, se si utilizza una vista personalizzata in ActionBar, è possibile impostare la visibilità della vista personalizzata su INVISIBLE in onDrawerSlide () e su VISIBLE in onDrawerClosed ().
Milano,

3

Sto utilizzando la libreria di supporto alla progettazione. E solo usando il tema personalizzato ho ottenuto la barra di stato trasparente quando è stato aperto il cassetto di navigazione.

inserisci qui la descrizione dell'immagine

inserisci qui la descrizione dell'immagine

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

Infine aggiungi il tema nel file manifest

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

Non dimenticare di utilizzare la proprietà, android:fitsSystemWindows="true"in "DrawerLayout"


1
come usarlo per dispositivi api di livello 19?
Android Acquista il

2

Questo è il più semplice e ha funzionato per me:

Nei valori-21:

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

Nei valori:

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

E imposta sulla barra degli strumenti

android:layout_marginTop="@dimen/topMargin"

Ho anche fatto questo, e ha funzionato come un fascino su Lollipop. Ma ho usato 24dpper il margine superiore.
Rafa,

Quando dividi lo schermo su dispositivi con Android 7.1 puoi vedere questo divario in alto se l'app è la seconda parte dello schermo.
Cícero Moura,

1

Invece di usare il ScrimInsetsFrameLayout... Non è più semplice aggiungere una vista con un'altezza fissa di 24dpe uno sfondo di primaryColor?

Capisco che ciò comporta l'aggiunta di una visione fittizia nella gerarchia, ma mi sembra più pulita.

L'ho già provato e funziona bene.

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

Quando dividi lo schermo su dispositivi con Android 7.1 puoi vedere questo divario in alto se l'app è la seconda parte dello schermo.
Cícero Moura,

0

Prova con questo:

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

stile :

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

L'attività principale estende ActionBarActivity

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

Ora puoi onCreateOptionsMenu apprezzare come normale ActionBar con ToolBar.

Questo è il mio layout

  • INIZIO: Cassetto sinistro - Cassetto destro
    • MID: ToolBar (ActionBar)
    • BOTTOM: ListFragment

Spero che tu capisca! Buon divertimento!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.