关于沉浸式设计,在国内指的是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-沉浸式设计的更多相关文章

  1. Android:UI 沉浸式体验,适合第一屏的引导图片、预览图片。

    链接:http://www.cnblogs.com/liushilin/p/5799381.html

  2. 沉浸式Web初体验

    沉浸就是让人专注在当前的情境下感到愉悦和满足,而忘记真实世界的情境.心流理论能有力解释人们废寝忘食地投入一件事情的状态. 心流理论的核心就是说当人的技能与挑战最佳匹配时能达到心流状态.比如玩一个游戏, ...

  3. Android 高级UI设计笔记07:RecyclerView 的详解

    1. 使用RecyclerView       在 Android 应用程序中列表是一个非常重要的控件,适用场合非常多,如新闻列表.应用列表.消息列表等等,但是从Android 一出生到现在并没有非常 ...

  4. Android UI体验之全屏沉浸式透明状态栏效果

    前言: Android 4.4之后谷歌提供了沉浸式全屏体验, 在沉浸式全屏模式下, 状态栏. 虚拟按键动态隐藏, 应用可以使用完整的屏幕空间, 按照 Google 的说法, 给用户一种 身临其境 的体 ...

  5. Android中的沉浸式状态栏效果

    无意间了解到沉浸式状态栏,感觉贼拉的高大上,于是就是试着去了解一下,就有了这篇文章.下面就来了解一下啥叫沉浸式状态栏.传统的手机状态栏是呈现出黑色条状的,有的和手机主界面有很明显的区别.这一样就在一定 ...

  6. Android状态栏微技巧,带你真正意义上的沉浸式

    记得之前有朋友在留言里让我写一篇关于沉浸式状态栏的文章,正巧我确实有这个打算,那么本篇就给大家带来一次沉浸式状态栏的微技巧讲解. 其实说到沉浸式状态栏这个名字我也是感到很无奈,真不知道这种叫法是谁先发 ...

  7. Android隐藏状态栏实现沉浸式体验

    转自: Android状态栏微技巧,带你真正理解沉浸式模式 什么叫沉浸式? 根据百度百科上的定义,沉浸式就是要给用户提供完全沉浸的体验,使用户有一种置身于虚拟世界之中的感觉. 那么对应到Android ...

  8. (原创)android4.4沉浸式标题栏

    趁着清明节的闲工夫,把我的百年不升级一次系统的红米note手机升级到了miuiv6的系统,早就听说android4.4的系统有沉浸式标题栏,一直没有体验过.这次终于有机会了.看了几个手机上常用的应用都 ...

  9. Android状态栏微技巧,带你真正理解沉浸式模式【转】

    感谢! 本文转自大佬郭霖:http://blog.csdn.net/guolin_blog/article/details/51763825 转载请注明出处:http://blog.csdn.net/ ...

随机推荐

  1. 系统字体放大导致rem布局错乱,解决方案,已通过测试

    如果你用rem没遇到过坑,那只能说明你 too young too simple; (function (doc, win) { var resizeEvt = 'orientationchange' ...

  2. TCP采用四次挥手关闭连接如图所示为什么建立连接协议是三次握手,而关闭连接却是四次握手呢?

    tcp四次挥手,由于TCP连接是全双工的,因此每个方向都必须单独进行关闭. 由于TCP连接是全双工的,因此每个方向都必须单独进行关闭.这个原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个 ...

  3. 44个Java性能优化

    44个Java性能优化 首先,代码优化的目标是: 减小代码的体积 提高代码运行效率 代码优化细节 1 .尽量指定类.方法的final修饰符 ​ 带有final修饰符的类是不可派生的.在Java核心AP ...

  4. Android根据内网外网连接情况配置服务器访问IP

    新项目的app,可通过内网和外网的服务器ip进行请求访问,但是客户提供了专业终端,终端在wifi情况下走外网内网都可以,但关闭wifi则只能走4G专网,也就是只能走内网. 可前往我的小站查看:Andr ...

  5. Qt 操作QDomDocument对象修改节点

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/liulihuo_gyh/article/d ...

  6. SelectKBest

    https://www.e-learn.cn/content/python/2198918from sklearn.feature_selection import SelectKBest,f_cla ...

  7. Python: 在CSV文件中写入中文字符

    0.2 2016.09.26 11:28* 字数 216 阅读 8053评论 2喜欢 5 最近一段时间的学习中发现,Python基本和中文字符杠上了.如果能把各种编码问题解决了,基本上也算对Pytho ...

  8. JVM 主动类和被动类的使用

    主动使用和被动使用Demo 1.创建工程一个Gradle工程 下一步 下一步 点击完成 2.创建类 public class MyTest1 { public static void main(Str ...

  9. 微信小程序之自定义底部弹出框动画

    最近做小程序时,会经常用到各种弹框.直接做显示和隐藏虽然也能达到效果,但是体验性太差,也比较简单粗暴.想要美美地玩,添加点动画还是非常有必要的.下面做一个底部上滑的弹框. wxml <view ...

  10. OGC open geospatial consortium标准服务

    数据共享作为GIS行业的基础,是每一位从事GIS相关领域人员必须要了解的知识,而OGC服务作为行业标准,已经被各大GIS厂商广泛应用.究竟什么是OGC呢? OGC全称——开放地理空间信息联盟(Open ...