J'essaie de dessiner des vues derrière la barre d'état comme ceci:
J'ai essayé de produire cet effet avec les techniques recommandées, mais j'obtiens ceci:
Il est clair d'après la capture d'écran qu'aucun contenu de mon application n'est dessiné derrière la barre d'état.
Ce qui est intéressant, c'est que le Nav Drawer parvient à dessiner derrière la barre d'état:
Choses que j'ai faites:
CoordinatorLayout
, AppBarLayout
, Toolbar
, DrawerLayout
windowTranslucentStatus
défini sur true
dans le thème de mon applicationfitsSystemWindows
défini sur true
sur mon CoordinatorLayout
Voici le thème de mon application:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@Android:color/transparent</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="Android:windowTranslucentStatus">true</item>
</style>
Voici ma structure d'activité:
<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:layout_width="match_parent"
Android:layout_height="match_parent"
Android:fitsSystemWindows="true"
tools:openDrawer="start">
<FrameLayout Android:id="@+id/page_container"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:fitsSystemWindows="true"/>
<Android.support.design.widget.NavigationView
Android:id="@+id/nav_view"
Android:layout_width="wrap_content"
Android:layout_height="match_parent"
Android:layout_gravity="start"
Android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/activity_main_drawer" />
</Android.support.v4.widget.DrawerLayout>
Le FrameLayout dans ma disposition d'activité est remplacé par cette disposition de fragment:
<Android.support.design.widget.CoordinatorLayout
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:layout_width="match_parent"
Android:layout_height="match_parent"
Android:fitsSystemWindows="true"
tools:context=".MainActivity">
<FrameLayout Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:paddingLeft="@dimen/activity_horizontal_margin"
Android:paddingRight="@dimen/activity_horizontal_margin"
Android:paddingTop="@dimen/activity_vertical_margin"
Android:paddingBottom="@dimen/activity_vertical_margin"
Android:background="@Android:color/holo_blue_bright"
tools:context=".MainActivity">
<TextView Android:text="@string/lorem_ipsum"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content" />
</FrameLayout>
<Android.support.design.widget.AppBarLayout
Android:layout_height="wrap_content"
Android:layout_width="match_parent"
app:elevation="0dp"
Android:theme="@style/AppTheme.TransparentAppBar">
<Android.support.v7.widget.Toolbar
Android:id="@+id/toolbar"
Android:layout_width="match_parent"
Android:layout_height="?attr/actionBarSize"
Android:background="@Android:color/transparent"
app:title="@string/hello_blank_fragment"
app:popupTheme="@style/AppTheme.OverflowMenu" />
</Android.support.design.widget.AppBarLayout>
<Android.support.design.widget.FloatingActionButton
Android:id="@+id/fab"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_gravity="bottom|end"
Android:layout_margin="@dimen/fab_margin"
Android:src="@Android:drawable/ic_dialog_email" />
</Android.support.design.widget.CoordinatorLayout>
modifier pour les futurs lecteurs: il y a beaucoup de bonnes informations sur le sujet et le problème dans les commentaires aussi, assurez-vous de les lire.
réponse originale: Votre thème est faux, c'est pourquoi. Malheureusement, il existe des différences sur la façon d'activer dans KitKat ou Lollipop. Sur mon code je l'ai fait en Java, mais vous pouvez aussi le réaliser en XML si vous voulez jouer avec les dossiers V21
De votre arborescence de ressources. Le nom des paramètres sera très similaire aux équivalents Java.
Supprimez le Android:windowTranslucentStatus
De votre XML et dans Java utilisez comme ça:
public static void setTranslucentStatusBar(Window window) {
if (window == null) return;
int sdkInt = Build.VERSION.SDK_INT;
if (sdkInt >= Build.VERSION_CODES.Lollipop) {
setTranslucentStatusBarLollipop(window);
} else if (sdkInt >= Build.VERSION_CODES.KitKat) {
setTranslucentStatusBarKiKat(window);
}
}
@TargetApi(Build.VERSION_CODES.Lollipop)
private static void setTranslucentStatusBarLollipop(Window window) {
window.setStatusBarColor(
window.getContext()
.getResources()
.getColor(R.color. / add here your translucent color code /));
}
@TargetApi(Build.VERSION_CODES.KitKat)
private static void setTranslucentStatusBarKiKat(Window window) {
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
alors vous pouvez appeler depuis votre activité setTranslucentStatusBar(getWindow());
modifier:
rendre la barre d'état translucide et la dessiner derrière elle (pour une raison que je ne comprends pas) sont deux tâches distinctes dans Android.
J'ai regardé plus sur mon code et je suis sûr d'avoir BEAUCOUP plus de Android:fitsSystemWindows="true"
Sur ma mise en page que juste le CoordinatorLayout
.
voici toutes les vues de ma mise en page avec Android:fitsSystemWindows="true"
dessus:
donc ma suggestion est de simplement tester/essayer de remplir Android:fitsSystemWindows="true"
sur votre XML.
styles.xml (v21)
<style name="MyTheme.NoActionBar.TransparentStatusBar">
<item name="Android:windowDrawsSystemBarBackgrounds">true</item>
<item name="Android:statusBarColor">@Android:color/transparent</item>
<item name="Android:windowTranslucentStatus">true</item>
</style>
Ensuite, si vous souhaitez modifier la couleur de la statubarc, vous devez supprimer TRANSLUENT_FLAG comme ceci
Window window = activity().getWindow();
if(showTransluent){
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.setStatusBarColor(Color.TRANSPARENT);
}else {
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.setStatusBarColor(ContextCompat.getColor(activity(), R.color.colorPrimaryDark));
}
Si je veux que StatusBar soit translucide et éloigne simultanément la vue de la dissimulation derrière StatusBar, j'utilise la plupart des vues parent FrameLayout avec argument
Mes styles.xml (v21) ressemblent
<resources>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="Android:windowDrawsSystemBarBackgrounds">true</item>
</style>
<style name="AppTheme.NoStatusBar" parent="AppTheme.NoActionBar">
<item name="Android:windowTranslucentStatus">true</item>
<item name="Android:windowTranslucentNavigation">true</item>
<item name="windowActionBarOverlay">true</item>
<item name="Android:windowActionBarOverlay">true</item>
</style>
</resources>
Et styles.xml
<style name="AppTheme" parent="Theme.AppCompat.Light">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
Peut-être que la clé du point ici est d'être sûr que vous utilisez AppCompactActivity ainsi que vous utilisez Theme.AppCompact comme racine pour vos styles.
C'était vraiment déroutant pour moi, mais je l'ai finalement compris pour ma combinaison de vues qui ressemble à ceci:
<Android.support.v4.widget.SwipeRefreshLayout - **no fitsSystemWindow set**
<Android.support.design.widget.CoordinatorLayout- Android:fitsSystemWindows="true"
<Android.support.design.widget.AppBarLayout - Android:fitsSystemWindows="true"
<Android.support.design.widget.CollapsingToolbarLayout - Android:fitsSystemWindows="true"
<RelativeLayout - Android:fitsSystemWindows="true"
<ImageView - Android:fitsSystemWindows="true"
J'ai également utilisé les méthodes publiées par Budius dans mon application pour faire fonctionner la barre d'état transparente:
Supprimez Android: windowTranslucentStatus de votre XML et dans Java utilisez comme ça:
public static void setTranslucentStatusBar(Window window) {
if (window == null) return;
int sdkInt = Build.VERSION.SDK_INT;
if (sdkInt >= Build.VERSION_CODES.Lollipop) {
setTranslucentStatusBarLollipop(window);
} else if (sdkInt >= Build.VERSION_CODES.KitKat) {
setTranslucentStatusBarKiKat(window);
}
}
@TargetApi(Build.VERSION_CODES.Lollipop)
private static void setTranslucentStatusBarLollipop(Window window) {
window.setStatusBarColor(
window.getContext()
.getResources()
.getColor(R.color. / add here your translucent color code /));
}
@TargetApi(Build.VERSION_CODES.KitKat)
private static void setTranslucentStatusBarKiKat(Window window) {
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}