Android材质:状态栏颜色不会改变

我正在开发一个简单的应用程序来testing材料devise。 我使用com.android.support:appcompat-v7:21.0.0 ,我的行为如下所示:

 public class MyActivity extends ActionBarActivity { ... } 

布局被定义为:

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

现在,我按照材料准则定义了我的主题:

 <style name="AppTheme" parent="Theme.AppCompat.NoActionBar"> <item name="colorPrimary">@color/colorPrimary500</item> <item name="colorPrimaryDark">@color/colorPrimaryDark700</item> </style> 

我想在Android 5之前更改状态栏的颜色,并将其设置为colorPrimaryDark但我找不到方法。 我试过使用:

 getWindow().setStatusBarColor(..) 

但setStatusBar颜色从21级可用。为什么如果我在我的主题中定义colorPrimaryDark并使用appcompact状态栏不会更改颜色? 任何人都可以帮忙

状态栏是操作系统拥有的系统窗口。 在5.0之前的Android设备上,应用程序没有改变其颜色的权限,所以AppCompat库不能支持旧版平台。 最好的AppCompat可以做的是为应用程序中的ActionBar和其他常见UI小部件着色提供支持。

虽然着色状态栏是不支持<5.0,在4.4你可以使用工作,以实现一个较暗的颜色:

使状态栏半透明

 <item name="android:windowTranslucentStatus">true</item> 

然后使用AppCompat的工具栏作为你的appbar,确保它适合系统窗口:

 <android.support.v7.widget.Toolbar android:id="@+id/toolbar" ... android:fitsSystemWindows="true"/> 

确保将您的工具栏设置为您的活动的工具栏:

 protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ... toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); 

工具栏延伸到状态栏下方,状态栏的半透明状态使其看起来是较暗的二级颜色。 如果这不是你想要的颜色,这个组合允许你在你的状态栏下面放置一个视图,体现你select的背景颜色(尽pipe它仍然被状态栏调暗)。

由于只有4.4的边缘案例解决方法,但有雅去。

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

把这段代码放在Activity的onCreate方法中。 这帮助了我。

正如其他人也提到的,这可以通过将以下内容添加到Activity的onCreate()中来解决:

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

不过,我想在这里添加的重要一点是,在某些情况下,即使是上述情况也不会改变状态栏的颜色。 例如,当为导航抽屉使用MikePenz库时,它显然会覆盖状态栏的颜色,因此您需要手动添加以下内容才能使其工作:

.withStatusBarColorRes(R.color.status_bar_color)

AppCompat v7:21.0.0不支持状态栏着色。

来自Android开发者的博客文章

在较老的平台上,AppCompat在可能的情况下模拟颜色主题。 目前这仅限于着色动作栏和一些小部件。

这意味着AppCompat lib将只能在棒棒糖和以上的颜色状态栏。

切换到AppCompatActivity,并在工具栏上添加一个25dp的paddingTop并打开

 <item name="android:windowTranslucentStatus">true</item> 

然后,将工具栏放在顶部

这个解决scheme设置了棒棒糖,奇巧和一些棒棒糖设备(三星和索尼)的状态栏颜色。 SystemBarTintManagerpipe理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); } 

使Theme.AppCompa t风格的父母

 <style name="AppTheme" parent="Theme.AppCompat"> <item name="android:colorPrimary">#005555</item> <item name="android:colorPrimaryDark">#003333</item> </style> 

onCreate()放置getSupportActionBar().getThemedContext() onCreate()

 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my); getSupportActionBar().getThemedContext(); } 

我知道这不能回答这个问题,但是使用Material Design(API 21+),我们可以在styles.xml的主题声明中添加这一行来更改状态栏的颜色:

 <!-- MAIN THEME --> <style name="AppTheme" parent="@android:style/Theme.Material.Light"> <item name="android:actionBarStyle">@style/actionBarCustomization</item> <item name="android:spinnerDropDownItemStyle">@style/mySpinnerDropDownItemStyle</item> <item name="android:spinnerItemStyle">@style/mySpinnerItemStyle</item> <item name="android:colorButtonNormal">@color/myDarkBlue</item> <item name="android:statusBarColor">@color/black</item> </style> 

注意android:statusBarColor ,我们可以在其中定义颜色,否则使用默认值。