关于沉浸式设计,在国内指的是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. ASM磁盘组的监控

    ASM磁盘组的监控可以使用oracle数据库查询,需要使用到的是sql语句和oracle数据库的相关操作. 还可以使用命令行进行查询,然后用awk进行文本拆分,拿到需要的值.这个需要使用到的是sudo ...

  2. C结构体struct 和 共用体union的使用测试

    #include <stdio.h> struct { char name[10]; char sex; char job; int num; union{ //联合只能共用同一个内存 i ...

  3. python-图像目标监测(1)识别答题卡

    # -*- coding: utf-8 -*- """ Created on Thu Dec 20 16:05:10 2018 @author: leizhen.liu ...

  4. 洛谷P2312解方程题解

    题目 暴力能得\(30\),正解需要其他的算法操作,算法操作就是用秦九韶算法来优化. 秦九韶算法就是求多项式的值时,首先计算最内层括号内一次多项式的值,然后由内向外逐层计算一次多项式的值,然后就将求\ ...

  5. 《挑战30天C++入门极限》入门教程:C++中的const限定修饰符

        入门教程:C++中的const限定修饰符 const修饰符可以把对象转变成常数对象,什么意思呢? 意思就是说利用const进行修饰的变量的值在程序的任意位置将不能再被修改,就如同常数一样使用! ...

  6. phpstorm 2019.1 修改选中内容背景色,以及匹配的内容背景色

    #与选中内容匹配的内容背景色Editor -> Color Scheme -> General -> Code -> Identifier under caret #选中内容前 ...

  7. window.location.href在微信端不起作用的解决方法?

    在我从第一张图的某个活动进去到详情页,点击返回是可以的,这里我是用了一个click事件,window.location.href="某死链接" 但是第二次进去点击之后点击事件是可以 ...

  8. X-NUCA-ezphp记录

    鸽了很久,还是记录一下 比赛的时候搞了很长时间,终于和mlt师傅搞出来了,竟然只有我们一队是预期解== <?php $files = scandir('./'); foreach($files ...

  9. html同行两个div浮动后下一个div怎么换行的问题

    传送门:https://blog.csdn.net/asdfg6541/article/details/78514535

  10. BAT 电脑名 用户名

    @echo offecho 当前盘符:%~d0echo 当前登陆用户:%username%echo 当前盘符和路径:%~dp0echo 当前盘符和路径的短文件名格式:%~sdp0echo 当前批处理全 ...