Inserisci il cassetto di navigazione sotto la barra di stato

Sto cercando di far andare il cassetto di navigazione sotto la barra di stato. Ho letto ampiamente la vista di ScrimInsetsFrameLayout e ho provato ad attuarlo, ma per qualche motivo non andrà sotto.

Ecco il codice che ho usato / scritto.

  • Problema di vulnerabilità Libpng anche dopo l'aggiornamento della libreria opencv
  • IndexNotReadyException - Android Studio
  • AlarmManager elimina tutti i programmi in fase di spegnimento?
  • android Uscire dalla modalità a schermo integer
  • Google GCMIntentService istanzia
  • Come utilizzare il codice di assembly ARM in un progetto Android?
  • XML DrawerLayout:

    <android.support.v4.widget.DrawerLayout android:id="@+id/drawer_layout" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <FrameLayout android:id="@+id/content_frame" android:layout_width="match_parent" android:layout_height="match_parent" /> <include layout="@layout/toolbar" /> </FrameLayout> <com.andrewq.planets.util.ScrimInsetsFrameLayout xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/linearLayout" android:layout_width="304dp" android:layout_height="match_parent" android:layout_gravity="start" android:fitsSystemWindows="true" app:insetForeground="#4000"> <ListView android:id="@+id/left_drawer" android:layout_width="match_parent" android:layout_height="match_parent" android:choiceMode="singleChoice" /> </com.andrewq.planets.util.ScrimInsetsFrameLayout> </android.support.v4.widget.DrawerLayout> 

    ScrimInsetsFrameLayout.java:

     package com.andrewq.planets.util; /* * 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. */ import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.support.v4.view.ViewCompat; import android.util.AttributeSet; import android.widget.FrameLayout; import com.andrewq.planets.R; /** * A layout that draws something in the insets passed to {@link #fitSystemWindows(Rect)}, ie 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 (ie when * {@link #fitSystemWindows(Rect)} is called. This is useful for setting padding on UI elements based on * UI chrome insets (eg 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); } } 

    E infine, qui sono i miei styles.xml per valori-v21:

     <?xml version="1.0" encoding="utf-8"?> <resources> <style name="AppThemeNavDrawer" parent="Theme.AppCompat.NoActionBar"> <item name="colorAccent">#F8F8F8</item> <item name="android:windowTranslucentStatus">true</item> <item name="windowActionBar">false</item> <item name="windowActionModeOverlay">true</item> <item name="android:windowDrawsSystemBarBackgrounds">true</item> <item name="android:statusBarColor">@android:color/transparent</item> </style> </resources> 

    Ho esaminato il codice sorgente dell'applicazione I / O 2014 e questa domanda, e non so cosa sia così diverso.

    Ecco uno screenshot di quello che ho finora less il cassetto sotto la barra di stato: Immagine dello schermo

    Ho tutto il resto che funziona perfettamente e questa è l'ultima cosa che devo fare. La guida è molto apprezzata!

    Edit:

    Per chiarire, voglio che l'image venga colorata sotto la barra di stato, proprio come nella maggior parte di Google Apps e Google Now.

    5 Solutions collect form web for “Inserisci il cassetto di navigazione sotto la barra di stato”

    Ci sono diversi approcci per arrivare al risultato desiderato. È ansible abilitare lo stile trasshiny o tramite codice.

    Ho creato un MaterialDrawer (che segue le linee guida per il design dei materiali di Android) che implementa tutto questo e gestisce tutto per te. Per saperne di più: https://github.com/mikepenz/MaterialDrawer/

    Se vuoi crearla da soli, dovrai sempre decidere quale sia l'api più bassa che vuoi sostenere e / o devi dividere i tuoi stili.

    Per consentire a translucentStatusbar, wherete essere alless su API v19 o creare uno stile separat per v19 + values-v19 Questo sarà in qualche modo come questo

     <style name="YourTheme.TranslucentStatus" parent="Theme.AppCompat.Light.NoActionBar"> <item name="android:windowTranslucentStatus">true</item> </style> 

    Quindi ora questo sposta il layout completo sotto la barra di stato. In quasi tutti i casi ora si desidera aggiungere l'imbottitura sulla parte superiore del contenuto del cassetto e il contenuto normale della visualizzazione.

    È ansible farlo aggiungendo 24dp imbottitura 24dp .

    Questa non è un'applicazione veramente bella. Quindi c'è un approccio diverso utilizzando lo ScrimInsetsLayout utilizzato nell'applicazione Google IO 2014. https://github.com/google/iosched/blob/master/android/src/main/java/com/google/samples/apps/iosched/ui/widget/ScrimInsetsFrameLayout.java

    Questo sarà il layout del tuo contenuto e puoi impostare il colore per la barra di stato. Puoi trovare un'istruzione dettagliata su come utilizzarla, qui: https://stackoverflow.com/a/26932228

    Richiede un certo tempo per abituarsi agli stili e / o alla ScrimInsetsLayout .

    EDIT:

    Un campione più complesso su come gestirlo in modo programmato:

     if (Build.VERSION.SDK_INT >= 19 && Build.VERSION.SDK_INT < 21) { //enable translucent statusbar via flags setTranslucentStatusFlag(true); } if (Build.VERSION.SDK_INT >= 19) { mActivity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); } if (Build.VERSION.SDK_INT >= 21) { //we don't need the translucent flag this is handled by the theme setTranslucentStatusFlag(false); //set the statusbarcolor transparent to remove the black shadow mActivity.getWindow().setStatusBarColor(Color.TRANSPARENT); } //add a padding to the content of the drawer (25dp on devices starting with api v19) mDrawerContentRoot.setPadding(0, mActivity.getResources().getDimensionPixelSize(R.dimen.tool_bar_top_padding), 0, 0); // define the statusBarColor mDrawerContentRoot.setInsetForeground(mStatusBarColor); private void setTranslucentStatusFlag(boolean on) { if (Build.VERSION.SDK_INT >= 19) { Window win = mActivity.getWindow(); WindowManager.LayoutParams winParams = win.getAttributes(); final int bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS; if (on) { winParams.flags |= bits; } else { winParams.flags &= ~bits; } win.setAttributes(winParams); } } 

    EDIT2:

    La soluzione completa per risolvere questo problema era la pulizia di tutti i layout che erano nel progetto. una combinazione di layout e stili provocavano i problemi.

    I cambiamenti completi possono essere trovati in questa richiesta di tiro: https://github.com/Andrew-Quebe/Planets-Gradle/commit/83e28c09253af6e807b6f4e94baca8fbca3fc7c8

    aggiungendo android:fitsSystemWindows="false" a DrawerLayout risolve il problema

    È necessario creare un nuovo stile.xml e mettere tale file nella cartella style-v19 poiché il metodo trasshiny della barra di stato non è disponibile per i dispositivi pre-kitkat.

     <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar" > <item name="android:windowTranslucentStatus">true</item> </style> 

    Dopo di che vedrai che la tua applicazione è sotto la barra di stato ma devi dare l'imbottitura a toolBar per l'implementazione esatta. Crea un dimen-v19 e aggiungi

    <dimen name="ToolBarPaddingTop">24dp</dimen>

    Usalo in ToolBar

     <android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/accent_material_light" android:theme="@style/ThemeOverlay.AppCompat.Dark" android:fitsSystemWindows="true" android:paddingTop="@dimen/ToolBarPaddingTop"> </android.support.v7.widget.Toolbar> 

    Credo che dovrai aggiungere android:fitsSystemWindows="true" al tag android.support.v4.widget.DrawerLayout .

    Questo è ciò che ha funzionato per me:

    • Impostare android:windowTranslucentStatus a true nel tuo stile predefinito nella cartella v21. Questo renderà la tua barra di stato quasi trasparente da Lollipop.
    • Definisci il colore della Toolbar degli Toolbar con il parametro android:colorPrimary nel tuo stile.
    • NON impostare android:fitsSystemWindows="true" nel tuo layout.
    • Aggiungere un imbottitura 24dp alla parte superiore della barra degli strumenti e alla parte superiore del cassetto, ma solo da Lollyipop. Il modo migliore per farlo è quello di aggiungere una nuova dimensione ai file dimens. Nella cartella valori impostare su 0, nei valori-v21 impostare a 24 dp e utilizzarlo sulla Toolbar e nel Drawer .
    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.