新手一枚,最近在看沉浸式状态栏和Toolbar,并尝试模仿QQ群管理页面中,图片延伸到状态栏的样式,实际操作中发现很多细节,在这里mark一下。
ActionBar的隐藏和Toolbar的设置
ActionBar的隐藏
第一种方法是在属性文件下的style
文件中,将应用的<style>
标签(也可以是自定义的style
标签)继承自Theme.AppCompat.Light.NoActionBar
,然后在AndroidManifest
文件中将theme
属性(可以是应用属性,也可以是Activity
中的主题属性)设置为上文中定义的<style>
属性名。
//styles.xml
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
//AndroidManifest
android:theme="@style/AppTheme"
还有一种简单的方法,但是必须要求自定义的Activity
继承于AppCompatActivity
,然后在onCreate()
中调用如下方法:
getSupportActionBar().hide();
注意可能会报出空指针异常的错误,这是因为你的Theme
继承了XXX.NoActionBar
等导致ActionBar
已经被隐藏了。
Toolbar的使用
Toolbar
的使用和设置见android:ToolBar详解(手把手教程)
这里直接贴出我的示例代码,在代码中有适当讲解。
---my_layout.xml---
<android.support.v7.widget.Toolbar
android:id="@+id/tool_bar"
android:theme="@style/ToolbarStyle" //这个主题是在style.xml中定义的,用于设置Toolbar的基本属性
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ff123123" //这个背景可以任意设置,注意后面的第一种沉浸式中颜色要与状态栏相同
toolbar:navigationIcon="@mipmap/ic_launcher_round" //最左边的导航图标
toolbar:title="@string/app_name" //主标题
toolbar:subtitle="nihao" //副标题
toolbar:titleTextColor="@android:color/white"
toolbar:subtitleTextColor="@android:color/white"
toolbar:popupTheme="@style/ThemeOverlay.AppCompat.Light"> //弹出菜单的主题
//Toolbar中搜索栏的输入控件
<EditText
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textColor="@android:color/white"
android:cursorVisible="false"/> //设置不显示光标
</android.support.v7.widget.Toolbar>
---ToolbarActivity---
private void initToolbar(){
toolbar = findViewById(R.id.tool_bar);
//设置导航图标的点击事件
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
toolbar.inflateMenu(R.menu.setting_menu); //加载在menu.xml中定义的菜单选项
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()){
case R.id.item_setting:
Toast.makeText(ToolbarActivity.this, "设置", Toast.LENGTH_SHORT).show();
break;
case R.id.item_night:
Toast.makeText(ToolbarActivity.this, "夜间", Toast.LENGTH_SHORT).show();
break;
}
return false;
}
});
}
沉浸式的实现和重叠问题的解决
沉浸式的实现网上有很多的开源库,在多个版本的android系统上表现的不一致,这里我用真机测试的,默认为5.0.2版本。真正的沉浸式用郭霖大神的话说,就是像王者荣耀那样,全屏显示并且只有点击特定位置才能弹出状态栏的那种,我这里就不管这么多了,反正我觉得沉浸式状态栏的用户体验也很好,干脆也这么称呼为“沉浸式”了。
使用沉浸式的环境有三种:
第一种是与
Toolbar
或ActionBar
配合,使状态栏的颜色与Bar
的颜色相同,例如QQ主界面上的效果。第二种是图片延伸到状态栏,将
Toolbar
设置成透明(或者只留下状态栏),并且状态栏也需要是透明的,图片可以看作是状态栏和Toolbar
的背景,例如QQ群设置页面中显示群图片的那部分。第三种就是全屏显示的效果,状态栏和导航栏全部移除,只有当点击特定位置的时候才会出现,例如游戏界面或视频播放界面。
第一种
先看效果
代码也很简单,设置好了Toolbar
以后,只需要将StatusBar
的颜色改为Toolbar
的颜色即可:
getWindow().setStatusBarColor(Color.parseColor("#ff123123"));
第二种
第二种实现的前提是布局文件的根布局不能使用
LinearLayout
,这样会导致图片无法与Toolbar融合,无法达到效果。
第二种是将图片延伸至状态栏,那么Toolbar
就显得很碍眼,所以需要将Toolbar
设置成透明:
---my_layout.xml---
android:background="#00000000"
可以发现图片延伸到了Toolbar
的下面,同理,状态栏也要设置成透明的:
getWindow().setStatusBarColor(Color.TRANSPARENT);
但是设置完了你会惊讶的发现,状态栏似乎没什么变化,图片也没有像想象的那样延伸到状态栏。其实状态栏是透明了,但是由于系统将状态栏划在了内容栏以外,所以在布局文件中,无论设置怎样的布局,都无法将图片延伸至状态栏。这时候要加上下面这段语句:
View view = getWindow().getDecorView();
int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
view.setSystemUiVisibility(option);
这段代码的意思就是获取当前Activity
所在Window
的根View
,然后将根View
的属性设置成布局全屏和布局稳定。配置上以后,图片就延伸到了状态栏了,但是还是有问题。因为允许布局延伸到状态栏,所以ToolBar
也跟着覆盖了状态栏的一部分,这就需要解决重叠问题。
重叠问题的解决办法:
重叠无非就是在Toolbar
上面没有状态栏的实体存在,挤不下去Toolbar
,所以可以在Toolbar
上设置一个View
用来占位,比如以RelativeLayout
为根布局,可以设置一个TextView
,高度为0dp,在Toolbar
中加上代码:android:layout_below="@id/status_bar"
,接下来就是在Activity
中获取状态栏的高度并赋值给该TextView
即可:
findViewById(R.id.status_bar).getLayoutParams().height = getStatusBarHeight();
private int getStatusBarHeight(){
int result = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen","android");
if (resourceId > 0) {
result = getResources().getDimensionPixelSize(resourceId);
}
return result;
}
还有一种较为简洁的方法,首先我们来了解下android:fitsSystemWindows
这个属性的作用:
既然是为系统界面预留一部分空间,那只要我们的设置,将状态栏保留,并设置成NoActionBar
模式,这样再调用android:fitsSystemWindows
就可以使Toolbar
自然地占据原本ActionBar
的宝座了。如何设置成NoActionBar
模式请看最开始的部分,接着只要在布局文件的Toolbar
中添加一行代码即可:
android:fitsSystemWindows="true"
效果如下:
第三种
第三种要的是打王者荣耀的那种快感,整个屏幕都是我的操作界面,甚至恨不得屏幕再大一点,程序员适配的再好一点,就能有开视野挂的快感。唯一能让我有影响的就是触摸状态栏的时候,下滑会划出状态栏,过些时间又恢复全屏。
第三种其实和Toolbar
没多大关系,想要是实现这种效果只需要三步,把下面这段代码复制到你的Activity
中的onCreate()
方法中,然后打开app,最后下滑状态栏,然后就没有然后了。
View decorView = getWindow().getDecorView();
decorView.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);
这些标志就不多说了,字面意思应该就理解的差不多了,实在不行百度下就ok,下面看下效果:
日常结语:沉浸式还有很多细节这里没有涉及到,包括状态栏字体颜色的更改等,这篇文章就是针对如何设置这三种沉浸式做了示范,也算是对自己学习过程中的鼓励吧。