我创建了一个应用程序,它有多个主题,并且动态变化.我的意思是在运行时用户可以选择不同的主题.以便UI组件在运行时颜色发生变化.我遇到了一个奇怪的问题.问题是状态栏颜色根据主题没有变化. statusBar始终保持初始主题颜色.
values-v21 / style.xml如下
<style name="AppTheme" parent="Theme.AppCompat.NoActionBar">
<item name="colorPrimary">@color/primary</item>
<item name="colorPrimaryDark">@color/primary_dark</item>
<item name="colorAccent">@color/accent</item>
<item name="android:textColorPrimary">@color/primary_text</item>
<item name="android:icon">@color/icons</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
</style>
values-v21/themes.xml is as below
===================================
<resources>
<style name="AppThemeRed" parent="Theme.AppCompat.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#F44336</item>
<item name="colorPrimaryDark">#D32F2F</item>
<item name="colorAccent">#FFCDD2</item>
<item name="android:textColorPrimary">#FFFFFF</item>
<item name="android:icon">@color/icons</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
</style>
<style name="AppThemeAmber" parent="Theme.AppCompat.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#FFC107</item>
<item name="colorPrimaryDark">#FFA000</item>
<item name="colorAccent">#FFEB3B</item>
<item name="android:textColorPrimary">#FFFFFF</item>
<item name="android:icon">@color/icons</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
</style>
<style name="AppThemeBlue" parent="Theme.AppCompat.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#3F51B5</item>
<item name="colorPrimaryDark">#303F9F</item>
<item name="colorAccent">#448AFF</item>
<item name="android:textColorPrimary">#FFFFFF</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
</style>
<style name="AppThemePurple" parent="Theme.AppCompat.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#9C27B0</item>
<item name="colorPrimaryDark">#7B1FA2</item>
<item name="colorAccent">#7C4DFF</item>
<item name="android:textColorPrimary">#FFFFFF</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
</style>
<style name="AppThemeYellow" parent="Theme.AppCompat.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#FFEB3B</item>
<item name="colorPrimaryDark">#FBC02D</item>
<item name="colorAccent">#CDDC39</item>
<item name="android:textColorPrimary">#FFFFFF</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
</style>
</resources>
当用户从主题选择对话框中选择主题时,我调用一个函数并为该活动设置主题,同时重新创建活动.
public static void onActivityCreateSetTheme(Activity activity)
{
switch (sTheme)
{
case 0:
activity.setTheme(R.style.AppThemeRed);
break;
case 1:
activity.setTheme(R.style.AppThemeAmber);
break;
default:
case 2:
activity.setTheme(R.style.AppTheme);
break;
case 3:
activity.setTheme(R.style.AppThemeBlue);
break;
case 4:
activity.setTheme(R.style.AppThemePurple);
break;
case 5:
activity.setTheme(R.style.AppThemeYellow);
break;
}
}
我在抽屉里使用NavigationView,抽屉下面的状态栏就没问题了.但状态栏没有获取当前主题的primaryDark颜色.它始终只采用默认主题(启动主题)颜色.
解决方法:
在onCreate()方法中通过setTheme(int resId)设置主题不会对StatusBar产生任何影响,因为它不是Activity本身的一部分.
因此,为了达到预期的效果,您需要以编程方式进行.这是一个解析R.attr.colorPrimaryDark的片段,如果SDK级别高于21,则为StatusBar设置它:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
init();
setContentView(R.layout.activity_management);
// Further code
}
private void init(){
// Set the Theme
setTheme(R.style.MyAppTheme);
if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
getwindow().setStatusBarColor(getAttributeColor(R.attr.colorPrimaryDark));
}
}
// Resolve the given attribute of the current theme
private int getAttributeColor(int resId) {
TypedValue typedValue = new TypedValue();
getTheme().resolveAttribute(resId, typedValue, true);
int color = 0x000000;
if (typedValue.type >= TypedValue.TYPE_FirsT_COLOR_INT && typedValue.type <= TypedValue.TYPE_LAST_COLOR_INT) {
// resId is a color
color = typedValue.data;
} else {
// resId is not a color
}
return color;
}
编辑
这种方法显然会覆盖通过android:statusBarColor设置的颜色.因此,如果您使用的是NavigationDrawer,并且您希望抽屉位于StatusBar的“下方”,则必须在打开抽屉后立即手动将StatusBar颜色设置为透明:
例
actionBarDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, mToolbar,
R.string.open_drawer_accessibility_desc,
R.string.close_drawer_accessibility_desc) {
@SuppressLint("NewApi")
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
super.onDrawerSlide(drawerView, slideOffset);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getwindow().setStatusBarColor(
getResources().getColor(android.R.color.transparent));
}
}
/** Called when a drawer has settled in a completely open state. */
@Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
}
/** Called when a drawer has settled in a completely closed state. */
@Override
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
}
};
}