如果不需要支持 4.4,建议使用 statusBarColor
如果需要支持 4.4,简易 4.4 使用 windowTranslucentStatus;
5.x 使用 statusBarColor/colorPrimaryDark
(本答案在 5.1 和 5.0 中的解决方式并不会影响软键盘和 EditText 的行为,4.4 暂时无法测试,如有朋友发现 bug 请指出,我会在回答中注明,以免其他人一起掉坑里)
21用的什么方法改变状态栏的颜色?
设置statusBarColor为transparent。以前我以为修改statusBarColor可以改变状态栏颜色,可是结果不行。修改状态栏颜色有2种方法
1、colorPrimaryDark
2、用java代码修改statusBarColor,这里用java代码修改statusBarColor有效果,但是在style里的android:statusBarColor设置值没有任何效果,不知道为什么
getWindow().setStatusBarColor(getResources().getColor(R.color.colorRed));
19用的是android:windowTranslucentStatus让状态栏透明,19用SystemBarTintManager来改变状态栏颜色,实际上是在decorview内加了一个view跟状态栏叠在一起(其实在contentview里加也是可以的)。而21用的是android:statusBarColor让状态栏透明。
如果21也用android:windowTranslucentStatus的话,会导致状态栏颜色很深,不符合MD。
https://blog.csdn.net/qq_34020571/article/details/78622642
状态栏的处理有两种不同的方式:
niorgai.github.io/2016/03/20/Android-transulcent-status-bar/
1:全屏( ContentView 可以进入状态栏)
2:非全屏 ( ContentView 与状态栏分离, 状态栏直接着色)
全屏模式: 左边图所示.
着色模式: 右边图所示.
ContentView: activity.findViewById(Window.ID_ANDROID_CONTENT) 获取的 View , 即 setContentView 方法所设置的 View, 实质为 FrameLayout. id/content
ContentParent: ContentView 的 parent , 实质为 LinearLayout.
ChildView: ContentView 的第一个子 View ,即布局文件中的 root layout .
三个view之间的关系:https://blog.csdn.net/c_cayujie/article/details/54381008
怎么获取Activity的ContentView?
方法1: Activity.findViewById(android.R.id.content) 首选
方法2: Activity.getWindow().getDecorView().findViewById(android.R.id.content)
方法3: Activity.findViewById(android.R.id.content).getRootView()
要想拿到布局文件的视图id,可以用这种方法:
((ViewGroup)findViewById(android.R.id.content)).getChildAt(0);
或getWindow().getDecorView().findViewById(android.R.id.content)
添加和删除组件:
public class MainActivity extends Activity {
private LinearLayout layout;
private TextView textView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
layout = new LinearLayout( this ); // 变量layout是该Activity的成员变量(private LinearLayout layout)
layout.setOrientation( LinearLayout.VERTICAL ); // 设置layout布局方向为垂直
setContentView( layout );
// 接下来向layout中添加TextView
textView = new TextView( this );
textView.setText( "This Is a TextView" );
layout.addView( textView );
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
layout.removeView(textView);
super.onResume();
}
Android 中的Activity、Window、View之间的关系:
https://www.cnblogs.com/kest/p/5141817.html
fitsSystemWindows, 该属性可以设置是否为系统 View 预留出空间, 当设置为 true 时,会预留出状态栏的空间.
FLAG_TRANSLUCENT_STATUS, 设置全屏的标志位, 此时界面可以延伸到状态栏.
5.0以上操作:
着色模式: 直接调用 setStatusBarColor 来设置状态栏的颜色
通过查看 setStatusBarColor() 方法的文档,发现在调用该方法时需要设置以下属性:
添加 FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS Flag(绘制系统栏).
清除 FLAG_TRANSLUCENT_STATUS Flag(透明状态栏).
调用 setStatusBarColor() 设置状态栏颜色.
即:
Window window = getWindow();
//取消设置透明状态栏,使 ContentView 内容不再覆盖状态栏
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
//需要设置这个 flag 才能调用 setStatusBarColor 来设置状态栏颜色
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
//设置状态栏颜色
window.setStatusBarColor(getResources().getColor(R.color.white));
全屏模式:
由于 5.0 以上为状态栏添加了一个阴影, 所以为全屏模式添加了是否隐藏状态栏阴影的方法.
隐藏阴影
像着色模式一样添加 flag ,然后通过 setStatusBarColor() 设置颜色为透明.
通过 setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) 隐藏状态栏颜色.
显示阴影
设置 FLAG_TRANSLUCENT_STATUS 来隐藏状态栏.
通过 setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE) 来恢复默认状态栏样式.
透明系统栏:
Translucent System Bar
4.4引入
情景一:没有Tab栏
1、在values、values-v19、values-v21的style.xml都设置一个 Translucent System Bar 风格的Theme
values/style.xml:
<style name="ImageTranslucentTheme" parent="AppTheme">
<!--在Android 4.4之前的版本上运行,直接跟随系统主题-->
</style>
values-v19/style.xml:
<style name="ImageTranslucentTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
values-v21/style.xml:
<style name="ImageTranslucentTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="android:windowTranslucentStatus">false</item>
<item name="android:windowTranslucentNavigation">true</item>
<!--Android 5.x开始需要把颜色设置透明,否则导航栏会呈现系统默认的浅灰色-->
<item name="android:statusBarColor">@android:color/transparent</item>
</style>
2、在AndroidManifest.xml中对指定Activity的theme进行设置
3、在Activity的布局文件中设置背景图片,同时,需要把android:fitsSystemWindows设置为true!
情景二:有Tab栏
<item name="android:statusBarColor">@color/color_31c27c</item>
需要用Toolbar,主题必须的NoActionBar,否则就在activity中setContentView()前调用requestWindowFeature(Window.FEATURE_NO_TITLE)。
代码中怎么获取内容布局的根布局,并设置setFitSystem为true:
ViewGroup contentFrameLayout = (ViewGroup) findViewById(Window.ID_ANDROID_CONTENT);
View parentView = contentFrameLayout.getChildAt(0);
if (parentView != null && Build.VERSION.SDK_INT >= 14)
{ parentView.setFitsSystemWindows(true);}
Decorview(是一个FrameLayout)
|—LinearLayout
|—FrameLayout 给ActionBar(当设置主题为NoActionBar是为ViewStub)
|—FrameLayout 给ContentView
只要我们在LinearLayout的第一个位置插入一个View就可以让ContentView下移了!
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.KITKAT)
{
ViewGroup firstChildAtDecorView = ((ViewGroup) ((ViewGroup) getWindow().getDecorView()).getChildAt(0));
View statusView = new View(this);
//颜色的设置可抽取出来让子类实现之
ViewGroup.LayoutParams statusViewLp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight());
statusView.setBackgroundColor(getResources().getColor(android.R.color.holo_blue_light));
firstChildAtDecorView.addView(statusView, 0, statusViewLp);
}
private int getStatusBarHeight() {
int resId = getResources().getIdentifier("status_bar_height","dimen","android");
if(resId>0){ return getResources().getDimensionPixelSize(resId);
}
return 0;
}
//透明状态栏和导航栏,隐藏ActionBar
getSupportActionBar().hide();
getWindow().getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN|View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
getWindow().setNavigationBarColor(Color.TRANSPARENT);
getWindow().setStatusBarColor(Color.TRANSPARENT);
setSystemUiVisibility(int visibility)方法可传入的实参为:
https://www.jianshu.com/p/3dc25a1ccb78
1. View.SYSTEM_UI_FLAG_VISIBLE:显示状态栏,Activity不全屏显示(即:应用平常的显示画面)。有Actionbar
2. View.INVISIBLE:隐藏状态栏,同时Activity会伸展全屏显示。有Actionbar
3. View.SYSTEM_UI_FLAG_FULLSCREEN:Activity全屏显示,且状态栏被隐藏覆盖掉。
4. View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN:Activity全屏显示,但状态栏不会被隐藏覆盖,状态栏依然可见,Activity顶端布局部分会被状态遮住。
5. View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION:效果同View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
6. View.SYSTEM_UI_LAYOUT_FLAGS:效果同View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN,Activity的焦点通过Back键和recent键不一样。 点击recent键再返回时,Activity顶端布局部分会被状态遮住。点击Back键再返回时,Activity顶端布局部分不会被状态遮住!
4 5 6效果相同,但是用处不大啊!
7. View.SYSTEM_UI_FLAG_HIDE_NAVIGATION:隐藏虚拟按键(导航栏)。有些手机会用虚拟按键来代替物理按键。
8. View.SYSTEM_UI_FLAG_LOW_PROFILE:状态栏显示处于低能显示状态(low profile模式),状态栏上一些图标显示会被隐藏。
Android4.4新特性又增加下面俩个:(Android 4.4新特性之开启全屏沉浸模式)
9. View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY:为粘性沉浸式模式。下拉只能显示状态栏,不能显示Actionbar!状态栏会自动隐藏。
10.View.SYSTEM_UI_FLAG_IMMERSIVE:为非粘性沉浸式。状态栏和导航栏下拉显示后不再自动隐藏。
11. View.SYSTEM_UI_FLAG_LAYOUT_STABLE:这个标志来帮助你的应用维持一个稳定的布局。
requestWindowFeature(Window.FEATURE_NO_TITLE);//隐藏标题栏
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);//隐藏状态栏