高级UI-沉浸式设计
关于沉浸式设计,在国内指的是Toolbar和系统状态栏相统一,而谷歌官方给出的沉浸式则是指整个界面为UI所用,而这里所说的沉浸式则是指的前者,涉及4.4和5.0及以上,4.4以下的Android做不出沉浸式设计
头部沉浸式
在5.0及以上可以很简单的实现沉浸式,统一头部和和Toolbar的色彩,其主要是实现方式有三种
使用注意事项
要对系统版本做判断,分为三种情况,4.4以下,4.4,5.0及以上
在虚拟按键的有无判别上,需要得到是否有虚拟按键,虚拟按键是否打开
其实只需要的带虚拟按键的高度,而虚拟按键的高度等于整个屏幕的高度减去内容部分view的高度,判断其是否大于0即可
5.0及以上
设置主题实现
在主题里面指定了colorPrimaryDark则实现了头部的沉浸式
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>
设置样式属性实现
<item name="android:statusBarColor">@android:color/black</item>
在代码中设置实现
getWindow().setStatusBarColor(getResources().getColor(android.R.color.darker_gray));
4.4系统
在4.4系统做沉浸式稍显复杂,因为没有官方的支持,只能自己去实现
设置属性样式实现
但不推荐这样使用,这样存在兼容性问题
<item name="android:windowTranslucentStatus">true</item>
代码中和布局属性设置实现
首先设置状态栏为透明,然后在此基础之上完成沉浸式设计
这段代码应该位于setContentView()前面,设置以后才开始布局的绘制,不然会不起作用
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
此时状态栏变为透明,但Toolbar却往上移了,因此需要解决这个问题
Toolbar设置android:fitsSystemWindows="true"可以达到想要的效果,原因在于这个属性规定了设置布局时候是否考虑当前系统窗口的布局,但伴随而来的问题是这样使用的前提是没有ScrollView且其包含EditView,如果存在这种情况,会造成Toolbar的下拉,基于此产生了通用的解决方案
首先在最外层容器设置android:fitsSystemWindows="true",然后将最外层容器(也可以修改android:windowBackground颜色)设置成状态栏想要的颜色,最后将剩下的布局再包裹一层正常的背景颜色,这样就解决了4.4版本的沉浸式设计
当然,还有很多其他思路,比如修改Toolbar的高度,设置Toolbar的paddingTop等
或者直接使用第三方解决方案:SystemTint
虚拟按键沉浸式
5.0及以上
和头部设置一样,在5.0及以上版本中,由于系统支持,可以直接使用系统方法解决
属性设置
<item name="android:navigationBarColor">@android:color/darker_gray</item>
代码设置
getWindow().setNavigationBarColor(Color.GREEN);
4.4
设置虚拟按键为透明
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
然后有两种设置方法:
一种直接使用布局控制其高度
使其虚拟按键高度小于等于设置的的View高度,这样也能实现底部沉浸式另一种方法就是布局加上代码的实现方式
在布局底部添加一个高度为1dp的view
动态设置底部View的高度为虚拟导航栏的高度
View view = findViewById(R.id.view);
LayoutParams params = view.getLayoutParams();
params.height += getNavigationBarHeight(this);
view.setLayoutParams(p);
private int getNavigationBarHeight(Context context) {
int statusHeight = -1;
try {
Class<?> clazz = Class.forName("com.android.internal.R$dimen");
Object object = clazz.newInstance();
String heightStr = clazz.getField("navigation_bar_height").get(object).toString();
int height = Integer.parseInt(heightStr);
statusHeight = context.getResources().getDimensionPixelSize(height);
} catch (Exception e) {
e.prinStackTrace();
}
return statusHeight;
}
Demo综合判断
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
public class BaseTranslucentActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//判断版本,如果[4.4,5.0)就设置状态栏和导航栏为透明
if(android.os.Build.VERSION.SDK_INT>=android.os.Build.VERSION_CODES.KITKAT
&&android.os.Build.VERSION.SDK_INT<android.os.Build.VERSION_CODES.LOLLIPOP){
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
//设置虚拟导航栏为透明
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
}
}
@SuppressLint("NewApi")
public void setOrChangeTranslucentColor(Toolbar toolbar,View bottomNavigationBar, int translucentPrimaryColor){
//判断版本,如果[4.4,5.0)就设置状态栏和导航栏为透明
if(android.os.Build.VERSION.SDK_INT>=android.os.Build.VERSION_CODES.KITKAT
&&android.os.Build.VERSION.SDK_INT<android.os.Build.VERSION_CODES.LOLLIPOP){
if(toolbar!=null){
//1.先设置toolbar的高度
LayoutParams params = toolbar.getLayoutParams();
int statusBarHeight = getStatusBarHeight(this);
params.height += statusBarHeight ;
toolbar.setLayoutParams(params );
//2.设置paddingTop,以达到状态栏不遮挡toolbar的内容
toolbar.setPadding(
toolbar.getPaddingLeft(),
toolbar.getPaddingTop()+getStatusBarHeight(this),
toolbar.getPaddingRight(),
toolbar.getPaddingBottom());
//设置顶部的颜色
toolbar.setBackgroundColor(translucentPrimaryColor);
}
if(bottomNavigationBar!=null){
//解决低版本4.4+的虚拟导航栏的
if(hasNavigationBarShow(getWindowManager())){
LayoutParams p = bottomNavigationBar.getLayoutParams();
p.height += getNavigationBarHeight(this);
bottomNavigationBar.setLayoutParams(p);
//设置底部导航栏的颜色
bottomNavigationBar.setBackgroundColor(translucentPrimaryColor);
}
}
}else if(android.os.Build.VERSION.SDK_INT>=android.os.Build.VERSION_CODES.LOLLIPOP){
getWindow().setNavigationBarColor(translucentPrimaryColor);
getWindow().setStatusBarColor(translucentPrimaryColor);
}else{
//<4.4的,不做处理
}
}
private int getNavigationBarHeight(Context context) {
return getSystemComponentDimen(this, "navigation_bar_height");
}
//获取状态栏的高度
private int getStatusBarHeight(Context context) {
return getSystemComponentDimen(this, "status_bar_height");
}
//反射手机运行的类:android.R.dimen
private static int getSystemComponentDimen(Context context, String dimenName){
int statusHeight = -1;
try {
Class<?> clazz = Class.forName("com.android.internal.R$dimen");
Object object = clazz.newInstance();
String heightStr = clazz.getField(dimenName).get(object).toString();
int height = Integer.parseInt(heightStr);
//dp -> px
statusHeight = context.getResources().getDimensionPixelSize(height);
} catch (Exception e) {
e.printStackTrace();
}
return statusHeight;
}
private static boolean hasNavigationBarShow(WindowManager wm){
Display display = wm.getDefaultDisplay();
DisplayMetrics outMetrics = new DisplayMetrics();
//获取整个屏幕的高度
display.getRealMetrics(outMetrics);
int heightPixels = outMetrics.heightPixels;
int widthPixels = outMetrics.widthPixels;
//获取内容展示部分的高度
outMetrics = new DisplayMetrics();
display.getMetrics(outMetrics);
int heightPixels2 = outMetrics.heightPixels;
int widthPixels2 = outMetrics.widthPixels;
int w = widthPixels-widthPixels2;
int h = heightPixels-heightPixels2;
return w>0||h>0;//竖屏和横屏两种情况。
}
}
public class MainActivity2 extends BaseTranslucentActivity{
private Toolbar toolbar;
private View navigation;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar)findViewById(R.id.toolbar);
navigation = findViewById(R.id.navigation);
setOrChangeTranslucentColor(toolbar, navigation, getResources().getColor(R.color.colorPrimary_pink));
}
}
高级UI-沉浸式设计的更多相关文章
- Android:UI 沉浸式体验,适合第一屏的引导图片、预览图片。
链接:http://www.cnblogs.com/liushilin/p/5799381.html
- 沉浸式Web初体验
沉浸就是让人专注在当前的情境下感到愉悦和满足,而忘记真实世界的情境.心流理论能有力解释人们废寝忘食地投入一件事情的状态. 心流理论的核心就是说当人的技能与挑战最佳匹配时能达到心流状态.比如玩一个游戏, ...
- Android 高级UI设计笔记07:RecyclerView 的详解
1. 使用RecyclerView 在 Android 应用程序中列表是一个非常重要的控件,适用场合非常多,如新闻列表.应用列表.消息列表等等,但是从Android 一出生到现在并没有非常 ...
- Android UI体验之全屏沉浸式透明状态栏效果
前言: Android 4.4之后谷歌提供了沉浸式全屏体验, 在沉浸式全屏模式下, 状态栏. 虚拟按键动态隐藏, 应用可以使用完整的屏幕空间, 按照 Google 的说法, 给用户一种 身临其境 的体 ...
- Android中的沉浸式状态栏效果
无意间了解到沉浸式状态栏,感觉贼拉的高大上,于是就是试着去了解一下,就有了这篇文章.下面就来了解一下啥叫沉浸式状态栏.传统的手机状态栏是呈现出黑色条状的,有的和手机主界面有很明显的区别.这一样就在一定 ...
- Android状态栏微技巧,带你真正意义上的沉浸式
记得之前有朋友在留言里让我写一篇关于沉浸式状态栏的文章,正巧我确实有这个打算,那么本篇就给大家带来一次沉浸式状态栏的微技巧讲解. 其实说到沉浸式状态栏这个名字我也是感到很无奈,真不知道这种叫法是谁先发 ...
- Android隐藏状态栏实现沉浸式体验
转自: Android状态栏微技巧,带你真正理解沉浸式模式 什么叫沉浸式? 根据百度百科上的定义,沉浸式就是要给用户提供完全沉浸的体验,使用户有一种置身于虚拟世界之中的感觉. 那么对应到Android ...
- (原创)android4.4沉浸式标题栏
趁着清明节的闲工夫,把我的百年不升级一次系统的红米note手机升级到了miuiv6的系统,早就听说android4.4的系统有沉浸式标题栏,一直没有体验过.这次终于有机会了.看了几个手机上常用的应用都 ...
- Android状态栏微技巧,带你真正理解沉浸式模式【转】
感谢! 本文转自大佬郭霖:http://blog.csdn.net/guolin_blog/article/details/51763825 转载请注明出处:http://blog.csdn.net/ ...
随机推荐
- Jenkins - Update information obtained: 不可用 ago;
Jenkins 添加插件 jenkins plugin提示: Update information obtained: 不可用 ago: 编辑 hudson.model.UpdateCenter.xm ...
- Sage Math中的语法
1.赋值后不能立即输出,而需要停顿.x= 3 不能输出显示,而 x= 3; x 可以显示. 2.可以用分号连续书写多行. 3.矩阵可以用 mtx[i, j]引用,但是行列号通常从0开始,维度n, m ...
- 编译安装和二进制安装mysql
二进制安装mysql-5.6.46 mysql二进制安装,已经编译成二进制了,只需要做一些配置即可 [root@localhost ~]$ yum install autoconf libaio -y ...
- linux 下终端通过证书、私钥快捷登录
ssh -i 你的证书 root@IP地址 -p 端口号 ssh -i {您的 .pem 文件的完整路径} ec2-user@{实例 IP 地址} 设置秘钥权限chmod 600 ~/.ssh/id_ ...
- golang orm
package main import ( "fmt" "github.com/astaxie/beego/orm" _"github.com/go- ...
- DM-移除几何上的洞
原视频下载地址:http://yunpan.cn/cujMhvXt4fCfa 访问密码 8afb
- 2018-2019-2 网络对抗技术 20165322 Exp8 Web基础
2018-2019-2 网络对抗技术 20165322 Exp8 Web基础 目录 实验原理 实验内容与步骤 Web前端HTML Web前端javascipt Web后端:MySQL基础:正常安装.启 ...
- Vue axios post 传参数,后台接收不到为 null
由于axios默认发送数据时,数据格式是Request Payload,而并非我们常用的Form Data格式,后端未必能正常获取到,所以在发送之前,需要使用qs模块对其进行处理. cnmp inst ...
- Java初级黄金体验 其一
关于作者 作者背景:公元2001年,意大利那不勒斯少年,为了达成梦想,在国庆的三天发现自己替身能力Java.从而加入了黑手党组织,并成为...... 作者目的:入门Java 为了Fighting Go ...
- Web Worker 使用教程【转】
原文:http://www.ruanyifeng.com/blog/2018/07/web-worker.html 一.概述 JavaScript 语言采用的是单线程模型,也就是说,所有任务只能在一个 ...