android 浸入式布局,Android中浸入式状态栏的使用

###前言

在Android开发过程中,我们为了让界面ui更美化的话,会涉及到浸入式状态栏的问题。我将此功能封装到两个类:

- StatusBarUtil 头部状态栏处理类

- NavigationBarUtil 底部按键栏处理类

那么,今天就让我们来讲讲浸入式状态栏相关知识吧。

今天涉及内容:

1. `StatusBarUtil`与`NavigationBarUtil`主要方法简介

1.1 `StatusBarUtil`方法简介

1.2 `NavigationBarUtil`方法简介

2. 浸入式状态栏的实现

2.1 浸入式头部状态栏实现

2.2 浸入式底部按键栏实现

2.3 浸入式头部状态栏和底部按键栏同时使用

2.4 隐藏显示底部按键栏

2.5 在含浸入式状态栏情况下显示和隐藏底部按键栏的处理

3. 效果图与项目结构图

先来波效果图

![](/contentImages/image/20200221/IY5bEtdIppblICKIr6H.gif)

#### 一. StatusBarUtil与NavigationBarUtil主要方法简介

##### 1.1 StatusBarUtil方法简介

`StatusBarUtil`类主要用来处理头部状态栏的浸入式效果,为了实现兼容性,其diamagnetic比较多也繁琐,这里主要介绍几个常用方法。

```

//设置状态栏背景透明

StatusBarUtil.immersive(context);

//设置状态栏背景红色

StatusBarUtil.immersive(context, ContextCompat.getColor(context,R.color.red));

//设置状态栏背景半透明红

StatusBarUtil.immersive(context, ContextCompat.getColor(context,R.color.red),0.5f);

注:目前状态栏文字颜色只有两种:白色和黑色

//设置状态栏文字变黑

StatusBarUtil.darkMode(context);

//设置状态栏文字变白

StatusBarUtil.darkMode(context,false);

//设置状态栏文字变黑

StatusBarUtil.darkMode(context,true);

//设置状态栏字体变黑,设置状态栏背景色和状态栏背景色的透明度

//参数介绍:

//activity: 上下文

//color:状态栏背景色

//alpha:状态栏背景色透明度

StatusBarUtil.darkMode(context, ContextCompat.getColor(this,R.color.red),0.5f);

```

为了简介起见,在使用过程中,我们通常只用以下方法:

```

//设置头部侵入式状态栏

StatusBarUtil.immersive(this);//设置状态栏透明

StatusBarUtil.setHeightAndPadding(this, mTvTitle);

StatusBarUtil.darkMode(this, true);//设置状态栏文字颜色为黑色:只有白色和黑色。true: 设置黑色 false: 设置白色

```

##### 1.2 NavigationBarUtil方法简介

`NavigationBarUtil`主要用于处理底部按键栏的浸入式效果,及处理底部按键栏的显示和隐藏效果。其主要有以下方法:

- 处理底部按键栏的浸入式效果的方法

```

/**

* 初始化时调用

*

* 注:rootView需要传具体的根view对象。

* 例如当你界面对应的xml中根布局为ConstraintLayout,

* 则此处rootView需要传ConstraintLayout实例。

*

* @param rootView 界面的根布局view对象

* @param context 上下文

*/

public static void initNavigationBar(View rootView,Context context)

/**

* 手机底部NavigationBar透明

* 在actiivty的onWindowFocusChanged()中调用

*

* @param context 上下文

* @param color 底部 颜色,如:Color.TRANSPARENT

*/

public static void onWindowFocusChanged(Context context,int color)

```

- 处理底部按键栏的显示和隐藏的方法

```

/**隐藏底部虚拟按键**/

public static void hideNavigationBar(Context context)

/**显示虚拟按键**/

public static void showNavigationBar(Context context)

```

#### 二.浸入式状态栏的实现

##### 2.1 浸入式头部状态栏实现

下面贴出在`MainActivity`中使用示例代码:

```

public class StatusBarActivity extends AppCompatActivity {

private TextView mTvTitle;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_statusbar);

mTvTitle=findViewById(R.id.tv);

//设置头部侵入式状态栏

StatusBarUtil.immersive(this);//设置状态栏透明

StatusBarUtil.setHeightAndPadding(this, mTvTitle);

StatusBarUtil.darkMode(this, true);//设置状态栏文字颜色为黑色

mTvTitle.setText("设置头部侵入式状态栏");

}

}

```

实现效果如下

![](/contentImages/image/20200221/7UD8ERUoipRzbnM7NJY.png)

##### 2.2 浸入式底部按键栏实现

下面贴出在`MainActivity`中使用示例代码:

```

public class NavigationActivity extends AppCompatActivity {

private ConstraintLayout mRootView;

private TextView mTvTitle;

//第一次进入当前activity的标志

private boolean isFirstCreated;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_statusbar);

mRootView=findViewById(R.id.root);

mTvTitle=findViewById(R.id.tv);

//设置侵入式底部按键栏

NavigationBarUtil.initNavigationBar(mRootView,NavigationActivity.this);

mTvTitle.setText("设置侵入式底部按键栏");

}

@Override

public void onWindowFocusChanged(boolean hasFocus) {

super.onWindowFocusChanged(hasFocus);

if(!isFirstCreated){

NavigationBarUtil.onWindowFocusChanged(NavigationActivity.this, Color.TRANSPARENT);

StatusBarUtil.setHeightAndPadding(this, mTvTitle);

isFirstCreated=true;

}

}

}

```

这里需要说明的是

- `initNavigationBar(mRootView,NavigationActivity.this)`方法中的`mRootView`为当前界面的具体根布局对象,不能笼统的使用抽取的父类(如baseActivity)中的根布局(如mLayoutView)代替使用,因为会出现界面控件全部没有的现象。若当前界面的根布局为`ConstraintLayout`,则此处的`mRootView`为`ConstraintLayout`控件实例。

- `onWindowFocusChanged(NavigationActivity.this, Color.TRANSPARENT)`方法需要在`Activity`的`onWindowFocusChanged`方法中执行,此处还需要结合`StatusBarUtil`类中的`StatusBarUtil.setHeightAndPadding(this, mTvTitle);`方法使用,为的是不至于在使用底部按键栏浸入效果时导致头部的标题栏出现显示异常的问题。为了防止界面重绘,我们还需要一个全局布尔值`isFirstCreated`来保证`Activity`的`onWindowFocusChanged`方法中关于浸入式处理只执行一次。

实现效果如下:

![](/contentImages/image/20200221/6ioxJxYpxGOOnuOyWLh.png)

##### 2.3 浸入式头部状态栏和底部按键栏同时使用

一个完美的效果,当然是期望头部与底部均实现浸入展示,则需要`StatusBarUtil`与`NavigationBarUtil`结合使用。在`MainActivity`中使用代码如下:

```

public class SNActivity extends AppCompatActivity {

private ConstraintLayout mRootView;

private TextView mTvTitle;

//第一次进入当前activity的标志

private boolean isFirstCreated;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_statusbar);

mRootView=findViewById(R.id.root);

mTvTitle=findViewById(R.id.tv);

//设置侵入式底部按键栏

NavigationBarUtil.initNavigationBar(mRootView,SNActivity.this);

mTvTitle.setText("设置侵入式头部底部状态栏");

}

@Override

public void onWindowFocusChanged(boolean hasFocus) {

super.onWindowFocusChanged(hasFocus);

if(!isFirstCreated){

NavigationBarUtil.onWindowFocusChanged(SNActivity.this, Color.RED);

//设置头部侵入式状态栏

StatusBarUtil.immersive(this);//设置状态栏透明

StatusBarUtil.setHeightAndPadding(this, mTvTitle);

StatusBarUtil.darkMode(this, true);//设置状态栏文字颜色为黑色

isFirstCreated=true;

}

}

}

```

实现效果如下:

![](/contentImages/image/20200221/J5D2PeaK3kYvi0X8u6Y.png)

##### 2.4 隐藏显示底部按键栏

这个主要涉及到`NavigationBarUtil`中关于显示和隐藏底部按键栏的方法,下面贴出在`MainActivity`中使用的示例代码:

```

public class HideWithoutActivity extends AppCompatActivity implements View.OnClickListener{

private ConstraintLayout mRootView;

private TextView mTvTitle;

private Button mBtn;

private Button mBtn2;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_hide);

mRootView=findViewById(R.id.root);

mTvTitle=findViewById(R.id.tv);

mBtn=findViewById(R.id.button);

mBtn2=findViewById(R.id.button2);

mBtn.setOnClickListener(this);

mBtn2.setOnClickListener(this);

}

@Override

public void onClick(View v) {

switch (v.getId()) {

case R.id.button://显示底部按键栏

NavigationBarUtil.showNavigationBar(HideWithoutActivity.this);

break;

case R.id.button2://隐藏底部按键栏

NavigationBarUtil.hideNavigationBar(HideWithoutActivity.this);

break;

default:

break;

}

}

}

```

显示效果如下:

![](/contentImages/image/20200221/0Gu2T75vuR4j68S0aIk.gif)

##### 2.5 在含浸入式状态栏情况下显示和隐藏底部按键栏的处理

这种情况是在界面已经有浸入式头部和底部的时候,又要处理底部按键栏遮挡问题时才会出现的处理。会涉及到浸入式效果的去掉和恢复问题。个人建议尽量避免此种情况的发生。要么就只使用浸入式效果,但不去涉及处理底部键盘显示和隐藏的动作,要么涉及到底部按键栏的显示和隐藏的时候就别设置浸入式效果。因为底部按键栏显示和隐藏的操作,会干扰到浸入式效果的呈现。

但是,这里还是写出这种情况下在`MainActivity`中的使用代码吧,请注意在底部按键栏显示和隐藏时关于浸入式效果的处理问题:

```

public class HideActivity extends AppCompatActivity implements View.OnClickListener{

private ConstraintLayout mRootView;

private TextView mTvTitle;

//第一次进入当前activity的标志

private boolean isFirstCreated;

private int mFirstTitleHeight;

private Button mBtn;

private Button mBtn2;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_hide);

mRootView=findViewById(R.id.root);

mTvTitle=findViewById(R.id.tv);

mBtn=findViewById(R.id.button);

mBtn2=findViewById(R.id.button2);

//设置侵入式底部按键栏

NavigationBarUtil.initNavigationBar(mRootView, HideActivity.this);

mTvTitle.setText("处理底部按键栏遮挡问题");

mBtn.setOnClickListener(this);

mBtn2.setOnClickListener(this);

}

@Override

public void onWindowFocusChanged(boolean hasFocus) {

super.onWindowFocusChanged(hasFocus);

LogUtil.i("=====onWindowFocusChanged========isFirstCreated="+isFirstCreated);

if(!isFirstCreated){

mFirstTitleHeight=mTvTitle.getHeight();

showStatusBar();

isFirstCreated=true;

}else{

LogUtil.i("=====onWindowFocusChanged========mFirstTitleHeight="+mFirstTitleHeight);

}

}

@Override

public void onClick(View v) {

switch (v.getId()) {

case R.id.button://显示底部按键栏

NavigationBarUtil.showNavigationBar(HideActivity.this);

//========以下为显示底部按键栏时对浸入式效果的处理===============

//设置侵入式底部按键栏

NavigationBarUtil.initNavigationBar(mRootView, HideActivity.this);

NavigationBarUtil.onWindowFocusChanged(HideActivity.this, Color.RED);

//设置头部侵入式状态栏

StatusBarUtil.immersive(this);//设置状态栏透明

StatusBarUtil.darkMode(this, true);//设置状态栏文字颜色为黑色

break;

case R.id.button2://隐藏底部按键栏

NavigationBarUtil.hideNavigationBar(HideActivity.this);

//========以下为隐藏底部按键栏时对浸入式效果的处理===============

mRootView.setPadding(0,0,0,0);

break;

default:

break;

}

}

private void showStatusBar(){

LogUtil.i("=====onWindowFocusChanged========mFirstTitleHeight="+mFirstTitleHeight);

NavigationBarUtil.onWindowFocusChanged(HideActivity.this, Color.RED);

//设置头部侵入式状态栏

StatusBarUtil.immersive(this);//设置状态栏透明

StatusBarUtil.setHeightAndPadding(this, mTvTitle);

StatusBarUtil.darkMode(this, true);//设置状态栏文字颜色为黑色

}

}

```

实现效果如下图:

![](/contentImages/image/20200221/T9m7BqGNqh7sYm7lpUI.gif)

#### 三.效果图与项目结构图

效果图如下:

![](/contentImages/image/20200221/IY5bEtdIppblICKIr6H.gif)

项目结构图如下:

![](/contentImages/image/20200221/iApGwewGkfrZhBmLMbi.png)

ok,今天的内容就讲到这里吧,谢谢大家。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值