先上代码和效果图
一、 在Activity中
1、activity_immerse.xml 布局中的代码:
* 隐藏系统自带的标题栏, 在需要实现沉浸式的布局中加入 android:fitsSystemWindows="true", 且该布局在页面需要在顶部显示
2、ImmerseActivity 中的代码
* 设置布局后, 添加沉浸式属性
/**
* 沉浸式状态栏
*/
public class ImmerseActivity extends BaseActivity {
@Override
public void setupViewLayout() {
setContentView(R.layout.activity_immerse);
//要实现沉浸式的布局, 一般是自定义的标题栏
LinearLayout ll_immerse_title = getViewNoClickable(R.id.ll_immerse_title);
//设置沉浸式状态栏效果
BasisImmerseUtils.setImmerseLayout(mActivity, ll_immerse_title);
}
}
3、BasisImmerUtils 工具类中 setImmerseLayout 方法
* 设置沉浸式属性方法
/**
* 设置沉浸式属性
*
* @param view 为实现沉浸式的布局, 需添加属性: android:fitsSystemWindows="true"
*/
public static void setImmerseLayout(Activity activity, View view) {
//沉浸式状态栏为Android4.4后特性
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Window window = activity.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);//设置透明状态栏属性
setPaddingTop(activity, view);
}
}
/**
* 将布局的PaddingTop增加系统栏的高度
*/
public static void setPaddingTop(Activity activity, View view) {
int statusBarHeight = getStatusBarHeight(activity);//获取系统状态栏高度
view.setPadding(view.getPaddingLeft(), view.getPaddingTop() + statusBarHeight, view.getPaddingRight(), view.getPaddingBottom());//设置view的paddingTop高度, 防止显示错乱
}
/**
* 获取系统状态栏高度
*
* @return pixel
*/
public static int getStatusBarHeight(Context context) {
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
return context.getResources().getDimensionPixelSize(resourceId);
}
return 0;
}
4、效果图
* 状态栏显示的就是我们设置的标题颜色, 其它是自定义标题栏测试
二、Activity 中 ViewPager + Fragment, Fragment布局实现沉浸式
1、activity_immersefragment.xml 布局中的代码
* viewpager需要是activity的第一个布局, 且需要设置activity的主题(theme)隐藏标题栏
2、ImmerseFragmentActivity 中代码
* 设置布局后, 添加沉浸式属性
/**
* 实现沉浸式状态栏Fragment
*/
public class ImmerseFragmentActivity extends BaseActivity {
private ViewPager vp_immersefragment;
private FragmentManager mFragmentManager = getSupportFragmentManager();
private ArrayList mFragments = new ArrayList<>();
public FragmentPagerAdapter mFragmentPagerAdapter;
public FragmentStatePagerAdapter mFragmentStatePagerAdapter;
@Override
public void setupViewLayout() {
setContentView(R.layout.activity_immersefragment);
BasisImmerseUtils.setImmerseLayout(mActivity);//设置沉浸式状态
// BasisImmerseUtils.hideStatusBar(mActivity);//隐藏顶部状态栏
// BasisImmerseUtils.hideNavigationBar(mActivity);//隐藏底部导航栏
// BasisImmerseUtils.setTransparentWindowBar(mActivity);//设置顶部状态栏和底部导航栏透明, 并使主题布局占据顶部和底部位置
}
@Override
public void initView() {
vp_immersefragment = getViewNoClickable(R.id.vp_immersefragment);
}
@Override
public void listener() {
}
@Override
public void logicDispose() {
initFragmentData();
setVPAdapter();
}
/**
* 初始化Fragment
*/
private void initFragmentData() {
mFragments.add(new Test1Fragment());
mFragments.add(new Test2Fragment());
mFragments.add(new Test3Fragment());
mFragments.add(new Test4Fragment());
mFragments.add(new Test5Fragment());
}
/**
* 设置适配器
*/
private void setVPAdapter() {
mFragmentPagerAdapter = new FragmentPagerAdapter(mFragmentManager) {
@Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
@Override
public int getCount() {
return mFragments == null ? 0 : mFragments.size();
}
};
/**
* 创建生命周期: onattach oncreate oncreateview onactivitycreated onstart onresume
* 销毁生命周期: onpause onstop ondestoryview ondestory ondetach
* 创建时会多执行 onattach oncreate
* 销毁时会多执行 ondestory ondetach
*/
mFragmentStatePagerAdapter = new FragmentStatePagerAdapter(mFragmentManager) {
@Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
@Override
public int getCount() {
return mFragments == null ? 0 : mFragments.size();
}
};
vp_immersefragment.setAdapter(mFragmentStatePagerAdapter);
}
@Override
public void onClick(View v) {
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
// BasisImmerseUtils.setOnWindowFocusChanged(mActivity, hasFocus);
}
}
3、Fragment 的布局 fragment_test1.xml 的代码
* 在需要实现沉浸式的布局中加入 android:fitsSystemWindows="true"
4、Fragment 中需添加下面的方法
* 设置沉浸式布局ll_fragment_test1的paddingtop, 防止显示异常
//设置沉浸式布局ll_fragment_test1的paddingtop, 防止显示异常
BasisImmerseUtils.setPaddingTop(mActivity, ll_fragment_test1);
5、BasisImmerUtils 工具类中 setPaddingTop 方法
/**
* 将布局的PaddingTop增加系统栏的高度
*/
public static void setPaddingTop(Activity activity, View view) {
int statusBarHeight = getStatusBarHeight(activity);//获取系统状态栏高度
view.setPadding(view.getPaddingLeft(), view.getPaddingTop() + statusBarHeight, view.getPaddingRight(), view.getPaddingBottom());//设置view的paddingTop高度, 防止显示错乱
}
/**
* 获取系统状态栏高度
*
* @return pixel
*/
public static int getStatusBarHeight(Context context) {
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
return context.getResources().getDimensionPixelSize(resourceId);
}
return 0;
}
6、效果图
* 其它Fragment类似, 在需要实现沉浸式的布局中加入 android:fitsSystemWindows="true"
三、说明
1、沉浸式原理,说明, 解说等已经有好多人进行了说明, 这里不再详细解说,只是简单给出实现沉浸式代码,在关联文章中也给出了两篇, 有兴趣可以看看
2、全屏大图的沉浸式类似,大家可自行尝试
3、Fragment 的沉浸式是为了不同 Fragment 需要不同自定义标题准备的, 若共用一个自定义标题, 使用Activity实现沉浸式更为简单
4、工具类 BasisImmerseUtils 中还包含一些隐藏导航栏, 全屏等方法,完整代码如下
package com.gingold.basislibrary.utils;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.os.Build;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
/**
* 沉浸式状态栏工具类
*
* @note viewPager中的Fragment自己使用沉浸式效果时, 占据状态栏的布局和标题布局需分开, 否则会引起标题显示错乱
*/
public class BasisImmerseUtils {
/**
* 设置沉浸式属性
*
* @param view 为实现沉浸式的布局, 需添加属性: android:fitsSystemWindows="true"
*/
public static void setImmerseLayout(Activity activity, View view) {
//沉浸式状态栏为Android4.4后特性
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Window window = activity.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);//设置透明状态栏属性
setPaddingTop(activity, view);
}
}
/**
* 将布局的PaddingTop增加系统栏的高度
*/
public static void setPaddingTop(Activity activity, View view) {
int statusBarHeight = getStatusBarHeight(activity);//获取系统状态栏高度
view.setPadding(view.getPaddingLeft(), view.getPaddingTop() + statusBarHeight, view.getPaddingRight(), view.getPaddingBottom());//设置view的paddingTop高度, 防止显示错乱
}
/**
* 设置沉浸式属性
*/
public static void setImmerseLayout(Activity activity) {
//沉浸式状态栏为Android4.4后特性
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Window window = activity.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);//设置透明状态栏属性
}
}
/**
* 取消沉浸式属性
*
* @param view 为实现沉浸式的布局, 需添加属性: android:fitsSystemWindows="true"
*/
public static void clearImmerseLayout(Activity activity, View view) {
//沉浸式状态栏为Android4.4后特性
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Window window = activity.getWindow();
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
int statusBarHeight = getStatusBarHeight(activity);//获取系统状态栏高度
view.setPadding(view.getPaddingLeft(), view.getPaddingTop() - statusBarHeight, view.getPaddingRight(), view.getPaddingBottom());//设置view的paddingTop高度, 防止显示错乱
}
}
/**
* 取消沉浸式属性
*/
public static void clearImmerseLayout(Activity activity) {
//沉浸式状态栏为Android4.4后特性
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Window window = activity.getWindow();
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
}
/**
* 获取系统状态栏高度
*
* @return pixel
*/
public static int getStatusBarHeight(Context context) {
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
return context.getResources().getDimensionPixelSize(resourceId);
}
return 0;
}
/**
* 设置顶部状态栏和底部导航栏透明, 并使主题布局占据顶部和底部位置
*
* 效果: 顶部状态栏和底部导航栏悬空在界面上
*/
public static void setTransparentWindowBar(Activity activity) {
//支持Android5.0以上版本
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
View decorView = activity.getWindow().getDecorView();
int option = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
decorView.setSystemUiVisibility(option);
activity.getWindow().setNavigationBarColor(Color.TRANSPARENT);
activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
}
}
/**
* 隐藏顶部状态栏
*/
public static void hideStatusBar(Activity activity) {
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN);
}
/**
* 隐藏底部导航栏
*/
public static void hideNavigationBar(Activity activity) {
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
}
/**
* 隐藏底部导航栏和顶部状态栏(点击任意位置效果消失)
*/
public static void hideStatusBarAndNavigationBar(Activity activity) {
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
}
/**
* 设置完全沉浸式效果(游戏和视频播放需求)
*
* 需要在onWindowFocusChanged方法中调用
*/
public static void setOnWindowFocusChanged(Activity activity, boolean hasFocus) {
if (hasFocus && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
activity.getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
}
}
四、相关文章
1、Android状态栏微技巧,带你真正理解沉浸式模式
2、Android沉浸式状态栏(透明状态栏)最佳实现
五、GitHup项目地址
https://github.com/GinGod/BasisDependency