HeLe小子拽
自从android4.4开始,android手机状态栏再也不是一成黑的时代,之前叫做变色龙,miui6发布会把他叫做沉浸式,之后大家就自然而然的接受了沉浸式这个名称,其实实际应该叫做Translucent Bar,即为透明状态栏。
沉浸式实现原理其实是使整个activity布局延伸到整个屏幕,然后使状态栏变成透明色,有些手机会有导航栏,同样也可以把导航栏变成透明色,这样会使一些app更加美观。
先看两个概念
-
状态栏
-
导航栏
1、引入
github仓库地址:https://github.com/gyf-dev/ImmersionBar
dependencies {
compile 'com.gyf.barlibrary:barlibrary:2.3.0'
}
2、特性
1)基本介绍
基础用法,建议在BaseActivity里调用
public class BaseActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ImmersionBar.with(this).init(); //初始化,默认透明状态栏和黑色导航栏
}
@Override
protected void onDestroy() {
super.onDestroy();
ImmersionBar.with(this).destroy(); //不调用该方法,如果界面bar发生改变,在不关闭app的情况下,退出此界面再进入将记忆最后一次bar改变的状态
}
}
- 高级用法,如果基础用法不能满足你的需求,可以试试这里的方法
ImmersionBar.with(this)
.transparentStatusBar() //透明状态栏,不写默认透明色
.transparentNavigationBar() //透明导航栏,不写默认黑色(设置此方法,fullScreen()方法自动为true)
.transparentBar() //透明状态栏和导航栏,不写默认状态栏为透明色,导航栏为黑色(设置此方法,fullScreen()方法自动为true)
.statusBarColor(R.color.colorPrimary) //状态栏颜色,不写默认透明色
.navigationBarColor(R.color.colorPrimary) //导航栏颜色,不写默认黑色
.barColor(R.color.colorPrimary) //同时自定义状态栏和导航栏颜色,不写默认状态栏为透明色,导航栏为黑色
.statusBarAlpha(0.3f) //状态栏透明度,不写默认0.0f
.navigationBarAlpha(0.4f) //导航栏透明度,不写默认0.0F
.barAlpha(0.3f) //状态栏和导航栏透明度,不写默认0.0f
.statusBarDarkFont(true) //状态栏字体是深色,不写默认为亮色
.flymeOSStatusBarFontColor(R.color.btn3) //修改flyme OS状态栏字体颜色
.fullScreen(true) //有导航栏的情况下,activity全屏显示,也就是activity最下面被导航栏覆盖,不写默认非全屏
.hideBar(BarHide.FLAG_HIDE_BAR) //隐藏状态栏或导航栏或两者,不写默认不隐藏
.addViewSupportTransformColor(toolbar) //设置支持view变色,可以添加多个view,不指定颜色,默认和状态栏同色,还有两个重载方法
.titleBar(view) //解决状态栏和布局重叠问题,任选其一
.statusBarView(view) //解决状态栏和布局重叠问题,任选其一
.fitsSystemWindows(true) //解决状态栏和布局重叠问题,任选其一,默认为false,当为true时一定要指定statusBarColor(),不然状态栏为透明色
.supportActionBar(true) //支持ActionBar使用
.statusBarColorTransform(R.color.orange) //状态栏变色后的颜色
.navigationBarColorTransform(R.color.orange) //导航栏变色后的颜色
.barColorTransform(R.color.orange) //状态栏和导航栏变色后的颜色
.removeSupportView(toolbar) //移除指定view支持
.removeSupportAllView() //移除全部view支持
.addTag("tag") //给以上设置的参数打标记
.getTag("tag") //根据tag获得沉浸式参数
.reset() //重置所以沉浸式参数
.keyboardEnable(true) //解决软键盘与底部输入框冲突问题,默认为false
.setOnKeyboardListener(new OnKeyboardListener() { //软键盘监听回调
@Override
public void onKeyboardChange(boolean isPopup, int keyboardHeight) {
LogUtils.e(isPopup); //isPopup为true,软键盘弹出,为false,软键盘关闭
}
})
.keyboardMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE) //单独指定软键盘模式
.init(); //必须调用方可沉浸式
2)详细介绍
解决状态栏和布局顶部重合
上面已经说了,沉浸式原理就是使整个布局延伸到状态栏和导航栏,既然这样必然导致一个问题,就是状态栏和布局顶部重叠,直接看图
https://upload-images.jianshu.io/upload_images/4776932-7f0f212167b8c81c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/700
眼神好的同学已经看到上图中给了五种解决方案啦,在这里说一下
1️⃣ 使用dimen自定义状态栏高度
在values-v19/dimens.xml文件下
25dp
在values/dimens.xml文件下
0dp
然后在布局界面添加view标签,高度指定为status_bar_height
2️⃣ 使用系统的fitsSystemWindows属性
在布局文件的根节点使用android:fitsSystemWindows="true"属性
然后使用ImmersionBar时候必须指定状态栏颜色
ImmersionBar.with(this)
.statusBarColor(R.color.colorPrimary)
.init();
3️⃣ 使用ImmersionBar的fitsSystemWindows(boolean fits)方法
实现原理是获得rootView的根节点,然后设置距离顶部的padding值为状态栏的高度值
ImmersionBar.with(this)
.statusBarColor(R.color.colorPrimary)
.fitsSystemWindows(true) //使用该属性必须指定状态栏的颜色,不然状态栏透明,很难看
.init();
4️⃣ 使用ImmersionBar的statusBarView(View view)方法
在标题栏的上方增加View标签(也可以为其他标签),高度指定为0dp
然后使用ImmersionBar的statusBarView方法,指定view就可以啦,实现原理:ImmersionBar获取状态栏的高度,传入view,设置高度为获取到的状态栏高度
ImmersionBar.with(this)
.statusBarView(view)
.init();
5️⃣ 使用ImmersionBar的titleBar(View view)方法
ImmersionBar.with(this)
.titleBar(view) //指定标题栏view
.init();
总结:这五种方法,任选其一使用就可以了,不要一起使用哦,根据项目而定,比如有侧边栏的,建议使用第1️⃣种或者第4️⃣种或者第5️⃣种,最后来一张效果图
-
在Fragment中实现沉浸式
注意:2.2.6版本已将ImmersionFragment这个类标记为过时,请用户自行使用懒加载方式实现
-
在Fragment使用ImmersionBar
第一种,当结合viewpager使用的时候,请使用懒加载的形式,参考demo中的BaseLazyFragment这个类
第二种,当使用show()和hide()来控制Fragment显示隐藏的时候,参考demo中的BaseTwoFragment这个类
注意:
- 2.2.7版本以后别忘了在Fragment的onDestroy方法里销毁沉浸式了,2.2.7版本之前不需要调用
@Override
protected void onDestroy() {
super.onDestroy();
if (mImmersionBar != null)
mImmersionBar.destroy();
}
以show()和hide()方式控制Fragment显示隐藏,别忘了重写onHiddenChanged方法,如下
@Override
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
if (!hidden && mImmersionBar != null)
mImmersionBar.init();
}
-
在Activity使用ImmersionBar
第一种,当结合viewpager使用的时候,请使用viewpager的addOnPageChangeListener的方法监听沉浸式,参考demo中FragmentThreeActivity这个类
第二种,当使用show()和hide()来控制Fragment显示隐藏的时候,请在tab切换的时候使用ImmersionBar,参考demo中FragmentFourActivity这个类
- 使用Fragment第三方框架Fragmentation实现沉浸式
参考demo中FragmentFiveActivity和BaseFiveFragment这个类