Je développe une application simple pour tester la conception du matériau. J'utilise com.Android.support:appcompat-v7:21.0.0
et mon activité ressemble à:
public class MyActivity extends ActionBarActivity {
...
}
La mise en page est définie comme suit:
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
tools:context=".MyActivity">
<Android.support.v7.widget.Toolbar
xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@+id/toolbar"
Android:layout_width="match_parent"
Android:layout_height="128dp"
Android:minHeight="?attr/actionBarSize"
Android:background="?attr/colorPrimaryDark"/>
</LinearLayout>
Maintenant, j'ai défini mon thème en suivant les directives matérielles:
<style name="AppTheme" parent="Theme.AppCompat.NoActionBar">
<item name="colorPrimary">@color/colorPrimary500</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark700</item>
</style>
J'aimerais modifier la couleur de la barre d'état dans la version antérieure à Android 5 et la définir sur colorPrimaryDark
, mais je ne trouve pas le chemin. J'ai essayé d'utiliser:
getWindow().setStatusBarColor(..)
mais la couleur setStatusBar est disponible à partir du niveau 21. Pourquoi si je définis un colorPrimaryDark
dans mon thème et que j'utilise appcompact, la barre d'état ne change pas de couleur? Tout le monde peut aider?
La barre d'état est une fenêtre système appartenant au système d'exploitation. Sur les appareils Android antérieurs à la version 5.0, les applications n’étant pas autorisées à modifier sa couleur, la bibliothèque AppCompat ne peut pas en prendre en charge les versions plus anciennes de la plateforme. Le meilleur qu'AppCompat puisse faire est de prendre en charge la coloration de ActionBar
et d'autres widgets d'interface utilisateur courants au sein de l'application.
Bien que la couleur de la barre d'état ne soit pas prise en charge <5.0, vous pouvez utiliser une solution de contournement pour obtenir une couleur plus sombre sous 4.4:
Rendre la barre d'état transparente
<item name="Android:windowTranslucentStatus">true</item>
Utilisez ensuite la barre d’outils AppCompat pour votre barre d’application, en vous assurant qu’elle s’adapte aux fenêtres système:
<Android.support.v7.widget.Toolbar
Android:id="@+id/toolbar"
...
Android:fitsSystemWindows="true"/>
Assurez-vous de définir votre barre d'outils en tant que barre d'outils de votre activité:
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
La barre d'outils s'étend sous la barre d'état et la semi-translucidité de la barre d'état lui donne une couleur secondaire plus sombre. Si ce n'est pas la couleur que vous souhaitez, cette combinaison vous permet d'ajuster une vue sous votre barre d'état affichant la couleur d'arrière-plan de votre choix (même si elle est toujours plus foncée dans la barre d'état).
Une sorte de solution de contournement pour les cas Edge en raison de la version 4.4 uniquement, mais voilà.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Lollipop) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
getWindow().setStatusBarColor(getResources().getColor(R.color.actionbar));
}
Placez ce code dans la méthode onCreate
de votre activité. Cela m'a aidé.
Comme d'autres l'ont également mentionné, cela peut être facilement résolu en ajoutant ce qui suit au onCreate () de l'activité:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Lollipop) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
getWindow().setStatusBarColor(ContextCompat.getColor(this, R.color.primary_dark));
}
Cependant, le point important que je veux ajouter ici est que, dans certains cas, même la procédure ci-dessus ne modifie pas la couleur de la barre d'état. Par exemple, lorsque vous utilisez la bibliothèque MikePenz pour Navigation Drawer, elle remplace implicitement la couleur de la barre d'état. Vous devez donc ajouter manuellement les éléments suivants pour que cela fonctionne:
.withStatusBarColorRes (R.color.status_bar_color)
La coloration de la barre d'état n'est pas prise en charge dans AppCompat v7: 21.0.0.
À partir du Blog de développeur Android
Sur les anciennes plates-formes, AppCompat émule la thématisation des couleurs dans la mesure du possible. Pour le moment, cela se limite à colorier la barre d’action et certains widgets.
Cela signifie que la bibliothèque AppCompat ne colorera que les barres d'état sur Lollipop et au-dessus.
Basculez vers AppCompatActivity et ajoutez un dp paddingTop de 25 dp dans la barre d’outils et activez-le.
<item name="Android:windowTranslucentStatus">true</item>
Ensuite, la barre d’outils va monter en haut en haut
Cette solution définit la couleur de la barre d'état de Lollipop, KitKat et de certains périphériques antérieurs à Lollipop (Samsung et Sony) . Le SystemBarTintManager gère les périphériques KitKat;)
@Override
protected void onCreate( Bundle savedInstanceState ) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
hackStatusBarColor(this, R.color.primary_dark);
}
@SuppressLint("NewApi")
@SuppressWarnings("deprecation")
public static View hackStatusBarColor( final Activity act, final int colorResID ) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Lollipop) {
try {
if (act.getWindow() != null) {
final ViewGroup vg = (ViewGroup) act.getWindow().getDecorView();
if (vg.getParent() == null && applyColoredStatusBar(act, colorResID)) {
final View statusBar = new View(act);
vg.post(new Runnable() {
@Override
public void run() {
int statusBarHeight = (int) Math.ceil(25 * vg.getContext().getResources().getDisplayMetrics().density);
statusBar.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, statusBarHeight));
statusBar.setBackgroundColor(act.getResources().getColor(colorResID));
statusBar.setId(13371337);
vg.addView(statusBar, 0);
}
});
return statusBar;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
else if (act.getWindow() != null) {
act.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
act.getWindow().setStatusBarColor(act.getResources().getColor(colorResID));
}
return null;
}
private static boolean applyColoredStatusBar( Activity act, int colorResID ) {
final Window window = act.getWindow();
final int flag;
if (window != null) {
View decor = window.getDecorView();
if (decor != null) {
flag = resolveTransparentStatusBarFlag(act);
if (flag != 0) {
decor.setSystemUiVisibility(flag);
return true;
}
else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KitKat) {
act.findViewById(Android.R.id.content).setFitsSystemWindows(false);
setTranslucentStatus(window, true);
final SystemBarTintManager tintManager = new SystemBarTintManager(act);
tintManager.setStatusBarTintEnabled(true);
tintManager.setStatusBarTintColor(colorResID);
}
}
}
return false;
}
public static int resolveTransparentStatusBarFlag( Context ctx ) {
String[] libs = ctx.getPackageManager().getSystemSharedLibraryNames();
String reflect = null;
if (libs == null)
return 0;
final String SAMSUNG = "touchwiz";
final String SONY = "com.sonyericsson.navigationbar";
for (String lib : libs) {
if (lib.equals(SAMSUNG)) {
reflect = "SYSTEM_UI_FLAG_TRANSPARENT_BACKGROUND";
}
else if (lib.startsWith(SONY)) {
reflect = "SYSTEM_UI_FLAG_TRANSPARENT";
}
}
if (reflect == null)
return 0;
try {
Field field = View.class.getField(reflect);
if (field.getType() == Integer.TYPE) {
return field.getInt(null);
}
} catch (Exception e) {
}
return 0;
}
@TargetApi(Build.VERSION_CODES.KitKat)
public static void setTranslucentStatus( Window win, boolean on ) {
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);
}
Marque Theme.AppCompa parent de style
<style name="AppTheme" parent="Theme.AppCompat">
<item name="Android:colorPrimary">#005555</item>
<item name="Android:colorPrimaryDark">#003333</item>
</style>
Et mettez getSupportActionBar().getThemedContext()
dans onCreate()
.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
getSupportActionBar().getThemedContext();
}