我正在开发一个简单的应用来测试材料设计。我使用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,状态栏不会改变颜色?
有人可以帮忙吗?
答案 0 :(得分:61)
状态栏是操作系统拥有的系统窗口。在5.0之前的Android设备上,应用程序无权更改其颜色,因此这不是AppCompat库可以支持旧平台版本的内容。 AppCompat可以做的最好的事情是为应用程序中的ActionBar
和其他常见UI小部件着色提供支持。
答案 1 :(得分:59)
虽然不支持着色状态栏&lt; 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);
工具栏延伸到状态栏下方,状态栏的半透明度使其看起来是较暗的二级颜色。如果这不是您想要的颜色,则此组合允许您在状态栏下方放置一个视图,该视图具有您选择的背景颜色(尽管状态栏仍然会使颜色变暗)。
由于4.4只有一种边缘情况解决方法,但是你去了。
答案 2 :(得分:39)
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
方法中。这帮助了我。
答案 3 :(得分:13)
正如其他人也提到过的,可以通过在活动的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)
答案 4 :(得分:10)
AppCompat v7:21.0.0中不支持状态栏着色。
来自Android developers blog post
在较旧的平台上,AppCompat尽可能模拟颜色主题。目前仅限于为操作栏和一些小部件着色。
这意味着AppCompat lib只会在Lollipop及更高版本上显示状态栏。
答案 5 :(得分:8)
切换到AppCompatActivity并在工具栏上添加25 dp paddingTop并打开
<item name="android:windowTranslucentStatus">true</item>
然后,将工具栏放在顶部
答案 6 :(得分:2)
此解决方案设置Lollipop,Kitkat和一些预制棒棒糖设备(三星和索尼)的状态栏颜色。 SystemBarTintManager正在管理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);
}
答案 7 :(得分:0)
制作 Theme.AppCompat t样式父
<style name="AppTheme" parent="Theme.AppCompat">
<item name="android:colorPrimary">#005555</item>
<item name="android:colorPrimaryDark">#003333</item>
</style>
并将getSupportActionBar().getThemedContext()
放入onCreate()
。
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
getSupportActionBar().getThemedContext();
}
答案 8 :(得分:0)
**
**
您好,我的主要问题是要比我的颜色更暗...所以这是避免使用TranslucentStatus解决方案中状态栏后面的阴影的解决方案...
因此,在您所有的Java活动中,您都需要这样做:
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);
}
,在您的styles.xml中,您需要设置背景颜色(该颜色将成为您的状态栏颜色):
<style name="AppCompat" parent="Theme.AppCompat">
<item name="android:colorBackground">@color/YOUR_STATUS_BAR_COLOR</item>
</style>
在所有布局中,您需要添加将作为背景的布局:
<LinearLayout
android:background="@color/YOUR_BACKGROUND_COLOR"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="bottom"
/>
当然,如果您想使用@ color / just name ...,则需要在colors.xml中进行设置:
<color name="YOUR_STATUS_BAR_COLOR">#cf031c</color>
<color name="YOUR_BACKGROUND_COLOR">#383838</color>
以下是我们如何完成此操作的整个过程:Whats the right approach to create or change color of a status bar?
答案 9 :(得分:-1)
我知道这不回答这个问题,但是使用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
,我们可以在其中定义颜色,否则使用默认值。