关于沉浸式的定义,这里不作争论...
透明状态栏,透明导航栏
通过主题配置
styles.xml
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"/>
</resources>
res下新建values-v19,values-v21文件夹
values-v19下添加styles.xml
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- 表示状态栏透明,并且会使得状态栏悬浮在activity之上(activity布局会扩展到状态栏底部) -->
<item name="android:windowTranslucentStatus">true</item>
<!-- 表示导航栏半透明,并且会使得状态栏和导航栏都悬浮在activity之上 -->
<item name="android:windowTranslucentNavigation">true</item>
</style>
</resources>
values-v21下添加styles.xml
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- 表示状态栏透明,并且会使得状态栏悬浮在activity之上(activity布局会扩展到状态栏底部) -->
<item name="android:windowTranslucentStatus">false</item>
<!-- 表示导航栏半透明,并且会使得状态栏和导航栏都悬浮在activity之上 -->
<item name="android:windowTranslucentNavigation">true</item>
<!--Android 5.x开始需要把颜色设置透明,否则导航栏会呈现系统默认的颜色-->
<item name="android:statusBarColor">@android:color/transparent</item>
</style>
</resources>
OK,我们看下我们的布局,然后看效果,布局随便写的,就是一个ScrollView套了一张图而已
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#1478d5"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/a"/>
</LinearLayout>
</ScrollView>
</LinearLayout>

下面我们看下效果:

[========]
使用代码实现
当然,记得styles.xml保留下NoActionBar
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"/>
</resources>
protected void initBar() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {//5.0及以上
//获取顶级窗口
View decorView = getWindow().getDecorView();
int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN //全屏标志,布局侵入
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION //标志布局会侵入到导航栏下
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE; //保持稳定
decorView.setSystemUiVisibility(option); //设置系统UI可见属性
getWindow().setStatusBarColor(Color.TRANSPARENT); //设置状态栏颜色透明
getWindow().setNavigationBarColor(Color.TRANSPARENT); //设置导航栏颜色透明
//设置状态栏为半透明
//getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
//设置导航栏为半透明
//getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {//4.4到5.0
WindowManager.LayoutParams localLayoutParams = getWindow().getAttributes();
localLayoutParams.flags = (WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS |
localLayoutParams.flags);
}
}
效果如下:

附赠:窗口的层级的经典图片

当然,你也可以设置导航栏为别的颜色
例如:
getWindow().setStatusBarColor(Color.parseColor("#581478d5")); //设置状态栏颜色
getWindow().setNavigationBarColor(Color.parseColor("#581478d5")); //设置导航栏颜色

或者你把这两句代码去掉,直接设置或者在主题编辑器中修改



效果如下:

附赠另一张经典图片:

[========]
有时候我们不想让布局中的内容也侵入到状态栏怎么办呢?
加个margin或padding呗!

效果如下:

等等walle9,我的特么的为什么是白乎乎的?
哈哈,难道你没看到我早已在LinearLayout上添加了一个颜色?...
可是我还有个问题,我就想让magin的值跟状态栏的高度一样怎么做呀?
嗯!写成30试试....或者代码中算一下高度呗!
其实我们还可以使用android:fitsSystemWindows这个属性来设置.
fitsSystemWindows只作用在sdk>=19的系统上就是高于4.4的系统
这个属性可以给任何view设置,只要设置了这个属性此view的所有padding属性失效.
只有在设置了透明状态栏(StatusBar)或者导航栏(NavigationBar)此属性才会生效
同时,所有设置了android:fitsSystemWindows=”true”属性的view会自动添加一个值等于状态栏高度的paddingTop,会自动添加一个值等于导航栏高度的paddingBottom
来呗!试一下!


顶出来了,有木有!
日了狗了!你又骗老子!
骚年啊!我没有骗你啊!下面的margin咱们忘记去掉了不是么!再试一下好咯!


恩恩!这次一样大了!
听说使用android:fitsSystemWindows="true"这个属性的view中的padding值会失效,咱们试试呗!
先试padding值:

效果如下:

加上android:fitsSystemWindows="true"

效果如下:

但是,需要注意哦,在我们滑动到最底部的时候,底部导航也会出现一个padding值,如果你介意的话,那就用magin或padding来设置.写个相近值或者代码中计算具体值.

下面我们在代码中计算:
没啥好说的,先设置一个id....

当然,你愿意在最外层那个linearlayout上面设置也可以,你高兴就好!
代码中找到这个控件,计算出状态栏的高度,设置padding...
private void initStatusBar() {
int statusBarHeight = getStatusBarHeight();
LinearLayout ll =findViewById(R.id.ll);
ll.setPadding(0,statusBarHeight,0,0);
}
获取状态栏高度:
private int getStatusBarHeight() {
int result = 0;
int resId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resId > 0) {
result = getResources().getDimensionPixelSize(resId);
}
return result;
}
再次附赠:获取导航栏高度
public float getNavigationBarHeight() {
float result = 0;
int resourceId = getResources().getIdentifier("navigation_bar_height", "dimen", "android");
if (resourceId > 0) {
result = getResources().getDimension(resourceId);
}
return result;
}
效果如下:

[========]
沉浸式
并不是所有的手机都像华为那样自带隐藏虚拟导航键的功能,虚拟导航键挡住了布局的底部导航怎么办呢?
骚年!看这里!自动隐藏导航...
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus && Build.VERSION.SDK_INT >= 19) {
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY //粘性沉浸体验
|View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION //布局侵入导航
|View.SYSTEM_UI_FLAG_HIDE_NAVIGATION //隐藏导航
//|View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN //全屏标记,布局侵入
//|View.SYSTEM_UI_FLAG_FULLSCREEN //隐藏状态栏
|View.SYSTEM_UI_FLAG_LAYOUT_STABLE //保持稳定
);
}
}
效果如下:

自动隐藏状态栏:
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus && Build.VERSION.SDK_INT >= 19) {
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY //粘性沉浸体验
|View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION //布局侵入导航
//|View.SYSTEM_UI_FLAG_HIDE_NAVIGATION //隐藏导航
|View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN //全屏标记,布局侵入
|View.SYSTEM_UI_FLAG_FULLSCREEN //隐藏状态栏
|View.SYSTEM_UI_FLAG_LAYOUT_STABLE //保持稳定
);
}
}
效果如下:

机智的你早已放开了一切...
那么恭喜你,你学会了沉浸式...
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus && Build.VERSION.SDK_INT >= 19) {
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY //粘性沉浸体验
|View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION //布局侵入导航
|View.SYSTEM_UI_FLAG_HIDE_NAVIGATION //隐藏导航
|View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN //全屏标记,布局侵入
|View.SYSTEM_UI_FLAG_FULLSCREEN //隐藏状态栏
|View.SYSTEM_UI_FLAG_LAYOUT_STABLE //保持稳定
);
}
}
效果如下:

over...
上传图片不容易,且复制且珍惜吧!
网友评论