安卓透明状态栏
- 讲下知识点:
- 屏幕最上边显示时间的那个地方交状态栏 StatusBar
- 屏幕最先变在有按键的地方,显示的叫 导航栏 NavigationBar
下面来讲具体做法:
1 . style样式
在默认的values里
<!--隐藏状态栏-->
<style name="ImageTranslucentTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!--在Android 4.4之前的版本上运行,直接跟随系统主题-->
</style>
在values-v19 里
<!--隐藏状态栏-->
<style name="ImageTranslucentTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">false</item>
</style>
在 values-v21里
<!--隐藏状态栏-->
<style name="ImageTranslucentTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">false</item>
<!--Android 5.x开始需要把颜色设置透明,否则导航栏会呈现系统默认的浅灰色-->
<item name="android:statusBarColor">@android:color/transparent</item>
</style>
这三个主题叫同一个名字,用来适配不同的版本,可以将他们设置给自定义的Application
<application
android:name=".MyApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/ImageTranslucentTheme">
这样就是全局生效,也可以不设置给Application 而设置给向采取这个效果的activity
<activity
android:name=".MainActivity"
android:theme="@style/ImageTranslucentTheme">
</activity>
然后在 想采取透明状态栏的布局的跟布局设置颜色 如下,就可以让透明状态栏编程想要的颜色
<RelativeLayout
android:id="@+id/activity_main"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/title_background_green"
>
但是当你跑起来时会有这样的效果,状态栏挤占了上边的空间,所以还需要第二步
- 在要显示透明状态栏的layout 里的跟布局写下如下代码 ,用来使自己的布局不挤占状态栏
android:fitsSystemWindows="true"
所以我的 MainActivity 的跟布局是这样的
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="@+id/activity_main"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:background="@color/title_background_green"
>
这就大功告成了,但是这样写太麻烦了,需要每个界面去添加,所以有 一种更简单的方法
写一个父类 activity 所有的activity 都继承他
public abstract class BaseActivity extends AppCompatActivity
在 BaseActivity 中重写 setContentView(int layoutResID) 方法,所有我们的activity子类在 onCreate(Bundle savedInstanceState) 方法中调用 setContentView(R.layout.main) 时 会走到父类的方法中 父类方法写下如下代码
@Override
public void setContentView(int layoutResID) {
//前两行是执行子类的 setContentView方法
View contentView = LayoutInflater.from(this).inflate(layoutResID, null);
setContentView(contentView);
// 不挤占状态栏
//拿到contentView 中的第一个childView 其实就是我们布局文件中的根布局
ViewGroup contentFrameLayout = (ViewGroup)findViewById(Window.ID_ANDROID_CONTENT);
View parentView = contentFrameLayout.getChildAt(0);
//只针对 14以上的app
if (parentView != null && Build.VERSION.SDK_INT >= 14) {
//改行相当于在跟布局的代码的中设置 android:fitsSystemWindows="true" 属性
parentView.setFitsSystemWindows(true);
//该行相当于在跟布局的代码中设置 android:background="@color/red" 属性
//parentView.setBackgroundColor(getResources().getColor(R.color.red));
}
}
这样一来 就剩下了在各个界面的根布局重复设置的过程
3. 最后一点问题 因为activity在启动时需要走闪屏页 ,我们希望的闪屏页效果如下
所以闪屏页状态栏要透明,并且下边的界面要挤占状态栏
做法: 加入闪屏页 叫 SplashActivity 同样继承 BaseActivity,然后修改BaseActivity中的代码为如下状态
@Override
public void setContentView(int layoutResID) {
View contentView = LayoutInflater.from(this).inflate(layoutResID, null);
setContentView(contentView);
ButterKnife.bind(this);
// 不挤占状态栏,同时 让闪屏页 不走这里 其余代码不变
if (!(this instanceof SplashActivity) ) {
ViewGroup contentFrameLayout = (ViewGroup) findViewById(Window.ID_ANDROID_CONTENT);
View parentView = contentFrameLayout.getChildAt(0);
if (parentView != null && Build.VERSION.SDK_INT >= 14) {
parentView.setFitsSystemWindows(true);
//parentView.setBackgroundColor(getResources().getColor(R.color.red));
}
}
}
同时在闪屏页的跟布局设置背景为给定的图片 到这里 效果就完了
一些 额外的发现
第一次做完后,放到华为6.0手机上跑 发现下边的虚拟按键的背景色也变了,弄了半天才明白,在原来的style样式中
<!--隐藏状态栏-->
<style name="ImageTranslucentTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">false</item>
<!--Android 5.x开始需要把颜色设置透明,否则导航栏会呈现系统默认的浅灰色-->
<item name="android:statusBarColor">@android:color/transparent</item>
<!--activity 跳转动画-->
<item name="android:windowAnimationStyle">@style/activityAnim</item>
</style>
当把如下代码中的 android:windowTranslucentNavigation 设置成 true 时 就会同样使用和状态栏相同的颜色,
所以反向推理,如果只想改变虚拟键盘的底色 可以设置成下边这样 ,就是反过来.
<item name="android:windowTranslucentStatus">false</item>
<item name="android:windowTranslucentNavigation">true</item>
当然他们都有设置颜色的属性 这个目前还没实验过,可以自行测试,
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
完成