Lollipop: dessine derrière StatusBar avec son jeu de couleurs transparent

J’ai défini la couleur de ma barre d’état sur Lollipop uniquement avec la ligne suivante dans mon thème:

@android:color/transparent 

Maintenant, je dois dessiner derrière, mais je ne peux pas obtenir de vue derrière elle. Je sais comment le faire avec la propriété windowTranslucentStatus , mais je ne veux pas utiliser cette propriété car elle ignorera alors la couleur du jeu de statusBar sur transparent.

Méthode n ° 1:

Pour obtenir une barre d’état complètement transparente, vous devez utiliser statusBarColor , qui n’est disponible que sur les API 21 et supérieures. windowTranslucentStatus est disponible sur les API 19 et supérieures, mais il ajoute un arrière-plan teinté à la barre d’état. Cependant, la définition de windowTranslucentStatus n’atteint pas une chose que le changement de statusBarColor en transparent ne fait pas: il définit les SYSTEM_UI_FLAG_LAYOUT_STABLE et SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN . Le moyen le plus simple d’obtenir le même effet est de définir manuellement ces indicateurs, ce qui désactive efficacement les encarts imposés par le système de disposition Android et vous laisse vous débrouiller tout seul.

Vous appelez cette ligne dans votre méthode onCreate :

 getWindow().getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); 

Veillez également à définir la transparence dans /res/values-v21/styles.xml:

 @android:color/transparent 

Ou définissez la transparence par programmation:

 getWindow().setStatusBarColor(Color.TRANSPARENT); 

Le bon côté de cette approche est que les mêmes mises en page et conceptions peuvent également être utilisées sur API 19 en échangeant la barre d’état transparente pour la barre d’état translucide teintée.

 true 

Méthode n ° 2:

Si vous ne devez peindre qu’une image d’arrière-plan sous votre barre d’état, au lieu de placer une vue derrière celle-ci, vous pouvez simplement définir l’arrière-plan du thème de votre activité sur l’image souhaitée et définir la transparence de la barre d’état comme indiqué dans la méthode # 1. C’est la méthode que j’ai utilisée pour créer les captures d’écran de l’ article d’ Android Police d’il y a quelques mois.

Méthode n ° 3:

Si vous devez ignorer les encarts système standard pour certaines mises en page tout en les gardant de travailler dans d’autres, la seule façon viable de le faire est de travailler avec la classe ScrimInsetsFrameLayout souvent associée. Bien sûr, certaines des choses faites dans cette classe ne sont pas nécessaires pour tous les scénarios. Par exemple, si vous ne prévoyez pas d’utiliser la superposition de la barre d’état synthétique, il vous suffit de commenter tout dans la méthode init() et de ne rien append au fichier attrs.xml. J’ai vu cette approche fonctionner, mais je pense que vous constaterez que cela a d’autres implications qui peuvent être très difficiles à contourner.

J’ai également vu que vous êtes opposé à la création de plusieurs mises en page. Dans le cas d’enrubannage d’une disposition à l’intérieur d’une autre, où les deux ont match_parent pour la hauteur et la largeur, les implications en match_parent de performances sont trop banales pour vous inquiéter. Quoi qu’il en soit, vous pouvez éviter complètement cette situation en modifiant la classe étendue de FrameLayout à tout autre type de classe de mise en page que vous aimez. Cela fonctionnera très bien.

Cela a fonctionné pour mon cas


 // Create/Set toolbar as actionbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); // Check if the version of Android is Lollipop or higher if (Build.VERSION.SDK_INT >= 21) { // Set the status bar to dark-semi-transparentish getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); // Set paddingTop of toolbar to height of status bar. // Fixes statusbar covers toolbar issue toolbar.setPadding(0, getStatusBarHeight(), 0, 0); } 

 // A method to find height of the status bar public int getStatusBarHeight() { int result = 0; int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); if (resourceId > 0) { result = getResources().getDimensionPixelSize(resourceId); } return result; } 

Pour plus d’informations sur l’utilisation des barres d’état: youtube.com/watch?v=_mGDMVRO3iE


Essayez ce thème

  

Assurez-vous que votre disposition

 android:fitsSystemWindows="false" 

Au lieu de

 @android:color/transparent 

Utilisez le suivant:

 true 

Et assurez-vous de supprimer le remplissage supérieur (qui est ajouté par défaut) dans votre mise en page “MainActivity”.

Notez que cela ne rend pas la barre d’état totalement transparente, et il y aura toujours une superposition “noir pâle” sur votre barre d’état.

La solution de Cody Toombs a failli faire l’affaire. Je ne suis pas sûr que ce soit lié à Xamarin ou non, mais j’ai maintenant une solution acceptable:

Exemple

Ceci est ma configuration:

J’ai un projet Android où j’ai référencé les packages Android.Support v4 et v7. J’ai deux styles définis:

values ​​/ styles.xml:

     

values-v21 / styles.xml:

     

Le Manifeste Android cible “MyStyle”:

AndroidManifest.xml:

       

Et enfin le code dans l’activité principale:

 [Activity (Label = "Test", MainLauncher = true, Icon = "@mipmap/icon")] public class MainActivity : Activity { protected override void OnCreate (Bundle savedInstanceState) { base.OnCreate (savedInstanceState); SetContentView (Resource.Layout.Main); //Resource.Layout.Main is just a regular layout, no additional flags. Make sure there is something in there like an imageView, so that you can see the overlay. var uiOptions = (int)Window.DecorView.SystemUiVisibility; uiOptions ^= (int)SystemUiFlags.LayoutStable; uiOptions ^= (int)SystemUiFlags.LayoutFullscreen; Window.DecorView.SystemUiVisibility = (StatusBarVisibility)uiOptions; Window.AddFlags (WindowManagerFlags.DrawsSystemBarBackgrounds); } } 

Notez que je mets le drapeau DrawsSystemBarBackgrounds, cela fait toute la différence

 Window.AddFlags (WindowManagerFlags.DrawsSystemBarBackgrounds); 

J’ai passé beaucoup de temps à bien faire les choses, trop de temps en fait. Espérons que cette réponse aide quiconque essaie de réaliser la même chose.

Vous pouvez utiliser ScrimInsetFrameLayout

https://github.com/google/iosched/blob/master/android/src/main/java/com/google/samples/apps/iosched/ui/widget/ScrimInsetsFrameLayout.java

android: fitsSystemWindows = “true” devrait définir la disposition du canevas!

Semblable à certaines des solutions affichées, mais dans mon cas, j’ai fait la barre d’état transparente et fixer la position de la barre d’action avec une marge négative

 if (Build.VERSION.SDK_INT >= 21) { getWindow().setStatusBarColor(Color.TRANSPARENT); FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) toolbar.getLayoutParams(); lp.setMargins(0, -getStatusBarHeight(), 0, 0); } 

Et j’ai utilisé dans la barre d’outils et la vue racine

 android:fitsSystemWindows="true" 

J’ai eu le même problème donc je crée ImageView qui dessine derrière la barre d’état API 19+

Définir une image personnalisée derrière la barre d’état gist.github.com

 public static void setTransparent(Activity activity, int imageRes) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { return; } // set flags if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); activity.getWindow().setStatusBarColor(Color.TRANSPARENT); } else { activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); } // get root content of system window //ViewGroup rootView = (ViewGroup) ((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0); // rootView.setFitsSystemWindows(true); // rootView.setClipToPadding(true); ViewGroup contentView = (ViewGroup) activity.findViewById(android.R.id.content); if (contentView.getChildCount() > 1) { contentView.removeViewAt(1); } // get status bar height int res = activity.getResources().getIdentifier("status_bar_height", "dimen", "android"); int height = 0; if (res != 0) height = activity.getResources().getDimensionPixelSize(res); // create new imageview and set resource id ImageView image = new ImageView(activity); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, height); image.setLayoutParams(params); image.setImageResource(imageRes); image.setScaleType(ScaleType.MATRIX); // add image view to content view contentView.addView(image); // rootView.setFitsSystemWindows(true); } 

La réponse de @Cody Toombs a entraîné un problème qui amène la mise en page derrière la barre de navigation. Donc, ce que j’ai trouvé utilise cette solution donnée par @Kriti

voici l’extrait de code Kotlin pour le même:

 if (Build.VERSION.SDK_INT >= 19 && Build.VERSION.SDK_INT < 21) { setWindowFlag(this, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, true) } if (Build.VERSION.SDK_INT >= 19) { window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN } if (Build.VERSION.SDK_INT >= 21) { setWindowFlag(this, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, false) getWindow().setStatusBarColor(Color.TRANSPARENT) } private fun setWindowFlag(activity: Activity, bits: Int, on: Boolean) { val win: Window = activity.getWindow() val winParams: WindowManager.LayoutParams = win.getAtsortingbutes() if (on) { winParams.flags = winParams.flags or bits } else { winParams.flags = winParams.flags and bits.inv() } win.setAtsortingbutes(winParams) } 

Vous devez également append

 android:fitsSystemWindows="false" 

vue racine de votre mise en page.

Avec Android Studio 1.4, le projet de modèle avec le code de plaque de la chaudière définit le thème Overlay sur votre AppbarLayout et / ou votre barre d’outils. Ils sont également configurés pour être rendus derrière la barre d’état par l’atsortingbut fitSystemWindow = true. Ainsi, seule la barre d’outils sera affichée directement sous la barre d’état et tout le rest sera affiché sous la barre d’outils. Les solutions fournies ci-dessus ne fonctionneront donc pas seules. Vous devrez apporter les modifications suivantes.

  • Supprimez le thème Superposition ou modifiez-le en thème non superposé pour la barre d’outils.
  • Placez le code suivant dans votre fichier styles-21.xml .

    @ android: couleur / transparent

  • Atsortingbuez ce thème à l’activité contenant le tiroir de navigation dans le fichier AndroidManifest.xml .

Cela rendra le tiroir de navigation à rendre derrière la barre d’état transparente.

Il existe une bonne bibliothèque StatusBarUtil à partir de @laobie qui permet de dessiner facilement des images dans StatusBar.

Ajoutez simplement votre build.gradle :

 comstack 'com.jaeger.statusbarutil:library:1.4.0' 

Puis dans l’ensemble d’activités

 StatusBarUtil.setTranslucentForImageView(Activity activity, int statusBarAlpha, View viewNeedOffset) 

Dans la mise en page

         

Pour plus d’informations, téléchargez la démo ou clonez depuis la page github et jouez avec toutes les fonctionnalités.

Remarque: supporte KitKat et ci-dessus.

J’espère que ça aide quelqu’un d’autre!

Voici le thème que j’utilise pour accomplir ceci:

  

La bonne solution consiste à modifier une propriété en XML sous votre balise d’activité en dessous du style. Ça marche

  android:theme="@style/Theme.AppCompat.Light.NoActionBar"