plus - cambiar barra de navegacion android p
Cajón de navegación semitransparente sobre la barra de estado no funciona (7)
¿Por qué no usar algo similar a esto?
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<ListView
android:id="@+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="@android:color/transparent"
android:dividerHeight="0dp"
android:background="#80111111"/>
</android.support.v4.widget.DrawerLayout>
El código anterior usa el recurso alfa en el android:background
para poder mostrar la transparencia dentro de la barra de acciones.
Hay otras formas de hacerlo a través del código, como muestran otras respuestas. Mi respuesta anterior, hace lo necesario en el archivo de diseño xml, que en mi opinión es fácil de editar.
Estoy trabajando en un proyecto de Android y estoy implementando el Cajón de navegación. Estoy leyendo las nuevas Especificaciones de diseño de materiales y la Lista de verificación de diseño de materiales .
La especificación dice que el panel deslizable debe flotar sobre todo lo demás, incluida la barra de estado, y ser semitransparente sobre la barra de estado.
Mi panel de navegación está sobre la barra de estado pero no tiene ninguna transparencia. He seguido el código de esta publicación de SO tal como se sugiere en el blog de desarrolladores de Google, enlace anterior. ¿Cómo uso DrawerLayout para mostrar en la Barra de herramientas / Barra de herramientas y debajo de la barra de estado? .
A continuación está mi diseño XML
<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">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<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="@color/appPrimaryColour" />
</LinearLayout>
<LinearLayout android:id="@+id/linearLayout"
android:layout_width="304dp"
android:layout_height="match_parent"
android:layout_gravity="left|start"
android:fitsSystemWindows="true"
android:background="#ffffff">
<ListView android:id="@+id/left_drawer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:choiceMode="singleChoice"></ListView>
</LinearLayout>
</android.support.v4.widget.DrawerLayout>
A continuación está mi tema de aplicaciones
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">@color/appPrimaryColour</item>
<item name="colorPrimaryDark">@color/appPrimaryColourDark</item>
<item name="colorAccent">@color/appPrimaryColour</item>
<item name="windowActionBar">false</item>
<item name="windowActionModeOverlay">true</item>
</style>
A continuación está mi tema de aplicaciones v21
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">@color/appPrimaryColour</item>
<item name="colorPrimaryDark">@color/appPrimaryColourDark</item>
<item name="colorAccent">@color/appPrimaryColour</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>
A continuación está mi método onCreate
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar);
setSupportActionBar(toolbar);
mDrawerLayout = (DrawerLayout)findViewById(R.id.my_drawer_layout);
mDrawerList = (ListView)findViewById(R.id.left_drawer);
mDrawerLayout.setStatusBarBackgroundColor(
getResources().getColor(R.color.appPrimaryColourDark));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
{
LinearLayout linearLayout =
(LinearLayout)findViewById(R.id.linearLayout);
linearLayout.setElevation(30);
}
A continuación se muestra una captura de pantalla de mi cajón de navegación que muestra que la parte superior no es semi transparente
El fondo de la barra de estado es blanco, el fondo de su cajón LinearLayout
. ¿Por qué? Usted es ajustes fitsSystemWindows="true"
para su DrawerLayout
y LinearLayout
dentro de él. Esto hace que LinearLayout
expanda detrás de la barra de estado (que es transparente). Por lo tanto, hacer que el fondo para la parte del cajón de la barra de estado sea blanco.
Si no desea que su cajón se extienda detrás de la barra de estado (desea tener un fondo semitransparente para toda la barra de estado), puede hacer dos cosas:
1) Simplemente puede eliminar cualquier valor de fondo de su LinearLayout
y colorear el fondo de su contenido dentro de él. O
2) Puede eliminar fitsSystemWindows="true"
de su LinearLayout
. Creo que este es un enfoque más lógico y más limpio. También evitará que se proyecte una sombra debajo de la barra de estado, donde su panel de navegación no se extiende.
Si desea que el cajón se extienda detrás de la barra de estado y tenga una superposición semitransparente del tamaño de la barra de estado, puede usar ScrimInsetFrameLayout
como contenedor para el contenido del cajón ( ListView
) y establecer el fondo de la barra de estado con la app:insetForeground="#4000"
. Por supuesto, puede cambiar #4000
a cualquier cosa que desee. ¡No olvides mantener fitsSystemWindows="true"
aquí!
O si no desea superponer su contenido y solo muestra un color sólido, puede establecer el fondo de su LinearLayout
en todo lo que desee. Sin embargo, ¡no olvide configurar el fondo de su contenido por separado!
EDITAR: Ya no es necesario tratar con nada de esto. Consulte Design Support Library para una implementación de Cajón de navegación / Vista mucho más fácil.
Si desea que el panel de navegación esté sobre la barra de estado y sea semitransparente sobre la barra de estado. Google I / O Android App Source proporciona una buena solución ( APK en Play Store no se actualiza a la versión perdida)
Primero necesitas un ScrimInsetFrameLayout
/*
* 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);
}
}
Luego, en su diseño XML, cambie esta parte
<LinearLayout android:id="@+id/linearLayout"
android:layout_width="304dp"
android:layout_height="match_parent"
android:layout_gravity="left|start"
android:fitsSystemWindows="true"
android:background="#ffffff">
<ListView android:id="@+id/left_drawer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:choiceMode="singleChoice"></ListView>
</LinearLayout>
Cambie LinearLayout a su ScrimInsetFrameLayout como este
<com.boardy.util.ScrimInsetFrameLayout
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="left|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"></ListView>
</com.boardy.util.ScrimInsetFrameLayout>
Tenía una característica similar para implementar en mi proyecto. Y para hacer que mi cajón sea transparente, simplemente uso la transparencia para los colores hexadecimales . Utilizando 6 dígitos hexadecimales, tiene 2 dígitos hexadecimales para cada valor de rojo, verde y azul, respectivamente. pero si pones dos dígitos adicionales (8 dígitos hexadecimales), entonces tienes ARGB (dos dígitos para el valor alfa) ( mira aquí ).
Aquí están los valores de opacidad Hex: para los 2 dígitos adicionales
100% — FF
95% — F2
90% — E6
85% — D9
80% — CC
75% — BF
70% — B3
65% — A6
60% — 99
55% — 8C
50% — 80
45% — 73
40% — 66
35% — 59
30% — 4D
25% — 40
20% — 33
15% — 26
10% — 1A
5% — 0D
0% — 00
Por ejemplo: si tiene color hexagonal (n. ° 111111), simplemente coloque uno de los valores de opacidad para obtener transparencia. como este: (# 11111100)
Mi gaveta no cubre la barra de acción (como la suya) pero la transparencia también se puede aplicar en estos casos. Aquí está mi código:
<ListView
android:id="@+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#11111100"
android:choiceMode="singleChoice"
android:divider="@android:color/transparent"
android:dividerHeight="0dp" />
</android.support.v4.widget.DrawerLayout>
Y aquí hay otro article que puede ayudarlo a comprender los códigos alfa en colores hexadecimales.
Todas las respuestas mencionadas aquí son demasiado antiguas y largas. La mejor y más corta solución que funciona con la última Navigationview es
@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);
}
}
esto va a cambiar el color de la barra de estado a transparente cuando abra el cajón
Ahora cuando cierra el cajón necesita cambiar el color de la barra de estado nuevamente a oscuro. Así puede hacerlo de esta manera.
@Override
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);
}
}
y luego en el diseño principal agregar una sola línea, es decir,
android:fitsSystemWindows="true"
y el diseño de su cajón se verá como
<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">
y su vista de navegación se verá como
<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"
/>
Lo he probado y funciona completamente. Espero que ayude a alguien. Puede que este no sea el mejor enfoque, pero funciona sin problemas y es fácil de implementar. Marcado si ayuda. Codificación feliz :)
Todo lo que necesita hacer es usar un poco de color semitransparente para la barra de estado. Agregue estas líneas a su tema v21:
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@color/desired_color</item>
No olvide que el color
(recurso) siempre debe tener el formato #AARRGGBB
. Esto significa que el color también incluirá el valor alfa.
ScrimLayout
ajustar el diseño de su cajón de navegación dentro de ScrimLayout
.
Un ScrimLayout
básicamente dibuja un rectángulo semitransparente sobre el diseño de su cajón de navegación. Para recuperar el tamaño del recuadro, simplemente anule fitSystemWindows
en su ScrimLayout
.
@Override
protected boolean fitSystemWindows(Rect insets) {
mInsets = new Rect(insets);
return true;
}
Más tarde anule el onDraw
para dibujar un rectángulo semitransparente.
Se puede encontrar una implementación de ScrimInsetFrameLayout en la fuente de la aplicación Google IO. Here puede ver cómo se usa en el diseño xml.