自从app换新需求(要做沉浸式状态栏),用过几种沉浸式状态栏,发现根本不能完全兼容Android 4.4以上所有版本,经过研究发现此种方法的确可行,在此记录。
以下代码在项目里,项目地址:https://gitee.com/urasaki/RxJava2AndRetrofit2
1.添加依赖
//沉浸式状态栏框架导入
// 基础依赖包,必须要依赖
implementation 'com.gyf.immersionbar:immersionbar:3.0.0'
// fragment快速实现(可选)
implementation 'com.gyf.immersionbar:immersionbar-components:3.0.0'
2.在values文件夹下的styles.xml文件下添加,并且把之前的名为AppTheme的style注释掉。
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowBackground">@android:color/white</item>
</style>
3.在清单文件的application标签下添加(如果没有则添加,如有则删除之前的,然后再添加)
android:theme="@style/AppTheme"
4.在清单文件的application标签内添加
<!-- 沉浸式状态栏适配 -->
<meta-data
android:name="android.max_aspect"
android:value="2.4" />
5.定义一个ImmerseGroup类
//沉浸式状态栏Toolbar辅助类,避免Toolbar设置fitSystemWindows="true"当软键盘弹出时Toolbar被拉伸
public class ImmerseGroup extends FrameLayout {
public ImmerseGroup(Context context) {
super(context);
}
public ImmerseGroup(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public ImmerseGroup(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setPadding(getPaddingLeft(), getPaddingTop(), getPaddingRight(), 0);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
6.在layout文件最上方中添加
<com.xxx.custom_view.ImmerseGroup
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorWhiteA"
android:minHeight="?attr/actionBarSize"
app:contentInsetStart="0dp">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="@dimen/dp_48">
<FrameLayout
android:id="@+id/layout_back"
android:layout_width="@dimen/dp_36"
android:layout_height="match_parent"
tools:ignore="UselessParent">
<ImageView
android:id="@+id/imv_back"
android:layout_width="@dimen/dp_6"
android:layout_height="@dimen/dp_11"
android:layout_gravity="center"
android:src="@mipmap/icon_arrowhead_left"
tools:ignore="ContentDescription" />
</FrameLayout>
<TextView
android:id="@+id/tev_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/feedback"
android:textColor="@color/colorBlackF"
android:textSize="@dimen/sp_17" />
</FrameLayout>
</androidx.appcompat.widget.Toolbar>
</com.xxx.custom_view.ImmerseGroup>
在Activity中添加函数
/**
* 设置沉浸式状态栏
* @param isDarkFont 状态栏字体是否是深色的
*/
protected void setToolbar(boolean isDarkFont, int color) {
if (isDarkFont) {
ImmersionBar.with(this) //原理:如果当前设备支持状态栏字体变色,会设置状态栏字体为黑色,
//如果当前设备不支持状态栏字体变色,会使当前状态栏加上透明度,否则不执行透明度
.statusBarColor(color) //状态栏颜色,不写默认透明色
.autoStatusBarDarkModeEnable(true, 0.2f) //自动状态栏字体变色,必须指定状态栏颜色才可以自动变色哦
.init();
} else {
ImmersionBar.with(this)
.statusBarColor(color) //状态栏颜色,不写默认透明色
.autoStatusBarDarkModeEnable(true, 0.2f) //自动状态栏字体变色,必须指定状态栏颜色才可以自动变色哦
.init();
}
}
//要在setContentView(R.layout.xxx)之后调用
setToolbar(true, getResources().getColor(R.color.colorWhiteB));
7.在Fragment中使用
在Fragment的layout文件最上方中添加
<View
android:id="@+id/status_bar_view"
android:layout_width="match_parent"
android:layout_height="0dp" />
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="@dimen/dp_73"
android:background="@color/colorWhiteB"
android:minHeight="?attr/actionBarSize"
android:orientation="vertical"
app:contentInsetStart="0dp"
tools:ignore="UselessParent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="@dimen/dp_73"
android:orientation="vertical">
<View
android:layout_width="match_parent"
android:layout_height="@dimen/dp_25" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="@dimen/dp_48"
android:visibility="visible"
tools:ignore="UselessParent">
<TextView
android:id="@+id/tev_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/historical_orders"
android:textColor="@color/colorBlackF"
android:textSize="@dimen/sp_17" />
<FrameLayout
android:id="@+id/layout_search"
android:layout_width="@dimen/dp_37"
android:layout_height="match_parent"
android:layout_gravity="end"
android:layout_marginEnd="@dimen/dp_37"
android:visibility="visible"
tools:ignore="UselessParent">
<ImageView
android:id="@+id/imv_search"
android:layout_width="@dimen/dp_15"
android:layout_height="@dimen/dp_15"
android:layout_gravity="center"
android:src="@mipmap/icon_search_order_black"
tools:ignore="ContentDescription" />
</FrameLayout>
<FrameLayout
android:id="@+id/layout_filter"
android:layout_width="@dimen/dp_37"
android:layout_height="match_parent"
android:layout_gravity="end"
android:visibility="visible"
tools:ignore="UselessParent">
<ImageView
android:id="@+id/imv_filter"
android:layout_width="@dimen/dp_15"
android:layout_height="@dimen/dp_15"
android:layout_gravity="center"
android:src="@mipmap/icon_filter"
tools:ignore="ContentDescription" />
</FrameLayout>
</FrameLayout>
</LinearLayout>
</androidx.appcompat.widget.Toolbar>
在Fragment的中添加
protected View statusBarView;
protected Toolbar toolbar;
protected void fitsLayoutOverlap() {
if (statusBarView != null) {
ImmersionBar.setStatusBarView(activity, statusBarView);
} else {
ImmersionBar.setTitleBar(activity, toolbar);
}
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
//旋转屏幕为什么要重新设置布局与状态栏重叠呢?因为旋转屏幕有可能使状态栏高度不一样,
//如果你是使用的静态方法修复的,所以要重新调用修复
fitsLayoutOverlap();
}
在Fragment的onCreateView函数中添加
rootView = inflater.inflate(R.layout.xxx, container, false);
statusBarView = rootView.findViewById(R.id.status_bar_view);
toolbar = rootView.findViewById(R.id.toolbar);
如对此有疑问,请联系qq1164688204。
推荐Android开源项目
项目功能介绍:RxJava2和Retrofit2项目,添加自动管理token功能,添加RxJava2生命周期管理,使用App架构设计是MVP模式和MVVM模式,同时使用组件化,部分代码使用Kotlin,此项目持续维护中。