Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Coloque el cajón de navegación debajo de la barra de estado

Estoy tratando de hacer mi cajón de navegación ir bajo la barra de estado. He leído extensamente acerca de la vista de ScrimInsetsFrameLayout y he intentado implementarla, pero por alguna razón no pasará.

Aquí está el código que usé / escribí.

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

Y finalmente, aquí está mi styles.xml para valores-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> 

He mirado el 2014 I / O app código fuente, así como esta pregunta, y no sé qué es tan diferente.

He aquí una captura de pantalla de lo que he hecho hasta ahora sin el cajón en la barra de estado: Captura de pantalla

Tengo todo lo demás trabajando perfectamente y esto es lo último que tengo que hacer. La ayuda es muy apreciada!

Editar:

Para aclarar, quiero que la imagen se coloree bajo la barra de estado como en la mayoría de Google Apps y Google Now.

  • Archivo proguard obsoleto; Usar -contienen a los miembros en vez de -contemplarlosconmiembros
  • Proyecto Android con Robolectric y Gradle (estudio Android)
  • Android geocoder ubicación inversa - forma fiable para obtener la ciudad?
  • Android Firebase - no puede obtener userid usando getUid () - Error: en la referencia de objeto nulo
  • Deja que el NetworkImageView de Volley muestre archivos de imágenes locales
  • JNI ERROR DETECTADO EN APLICACIÓN
  • Cómo iniciar sugerencias de inmediato en Android búsqueda antes de que el usuario incluso ha comenzado a escribir
  • ¿Cómo hago que un escáner de huellas digitales USB esté conectado a un teléfono móvil / tablet con éxito?
  • 5 Solutions collect form web for “Coloque el cajón de navegación debajo de la barra de estado”

    Hay diferentes enfoques para llegar al resultado deseado. Puede habilitar translúcido a través de estilo o mediante código.

    He creado un MaterialDrawer (que sigue las directrices de diseño de materiales de Android), que implementa todo esto y se encarga de todo para usted. Más información aquí: https://github.com/mikepenz/MaterialDrawer/

    Si desea crearlo por su cuenta siempre tiene que decidir cuál es el api más bajo que desea apoyar y / o si tiene que dividir sus estilos.

    Así que para habilitar translucentStatusbar tienes que estar al menos en API v19 o crear un estilo separador para v19 + values-v19 Esto se verá de alguna manera como esto

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

    Así que ahora esto moverá su diseño completo debajo de la barra de estado. En casi todos los casos, ahora querrá agregar el relleno en la parte superior del contenido del cajón y su contenido de vista normal.

    Puede hacerlo añadiendo 24dp relleno.

    Esto no es una implementación realmente agradable. Por lo tanto, hay un enfoque diferente utilizando ScrimInsetsLayout que se utiliza en la aplicación Google IO 2014. https://github.com/google/iosched/blob/master/android/src/main/java/com/google/samples/apps/iosched/ui/widget/ScrimInsetsFrameLayout.java

    Ésta será la disposición de su contenido y usted puede fijar el color para la barra de estado en él. Puede encontrar instrucciones detalladas sobre cómo utilizarlo, aquí: https://stackoverflow.com/a/26932228

    Requiere algún tiempo para acostumbrarse a los estilos y / o ScrimInsetsLayout .

    EDITAR:

    Un ejemplo más complejo sobre cómo puede manejar esto de forma programática:

     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 solución completa para solucionar este problema era limpiar todos los diseños que estaban en el proyecto. Alguna combinación de los diseños y estilos estaban causando los problemas.

    Los cambios completos se pueden encontrar en esta solicitud de extracción: https://github.com/Andrew-Quebe/Planets-Gradle/commit/83e28c09253af6e807b6f4e94baca8fbca3fc7c8

    Añadiendo android:fitsSystemWindows="false" a DrawerLayout resolverá el problema

    Debe crear un nuevo styles.xml y poner ese archivo en la carpeta style-v19 porque el método translúcido de la barra de estado no está disponible para los dispositivos pre kitkat.

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

    Después de que usted verá su la aplicación está bajo la barra de estado Pero usted necesita dar relleno a la barra de herramientas para la ejecución exacta.Crear un dimen-v19 y agregar

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

    Utilícelo en la barra de herramientas

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

    Creo que necesitas añadir android:fitsSystemWindows="true" a la etiqueta android.support.v4.widget.DrawerLayout también.

    Esto es lo que funcionó para mí:

    • Establezca android:windowTranslucentStatus a true en su estilo predeterminado en la carpeta v21. Esto hará que su barra de estado sea casi transparente de Lollipop.
    • Defina el color de su Toolbar de Toolbar con el parámetro android:colorPrimary en su estilo.
    • NO establezca android:fitsSystemWindows="true" en su diseño.
    • Añadir un relleno de 24dp a la parte superior de su barra de herramientas Y a la parte superior de su cajón, así, pero sólo de Lollyipop. La mejor manera de hacerlo es agregar una nueva dimensión a sus archivos dimens. En la carpeta valores, establezca en 0, en los valores-v21 establezca en 24 dp, y úselo en su Toolbar y Drawer .
    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.