高级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/ ...
随机推荐
- redis堵死致数据清空
情景: zy的链路监控突然都恢复,而且在哪个时间段zabbix中显示回复,也发送了告警,但是实际上告警并没有发出来.这是不可能的情况,应该是redis缓存中的数据都被清空了,没有认为干预,需解决问题 ...
- Luogu P3810 【模板】三维偏序(陌上花开) CDQ分治 树状数组
https://www.luogu.org/problemnew/show/P3810 复习板子,重要的题就真的要写三遍???之前写过一篇博客了,不过之前写的那个板子的sort用的规则真是沙雕 #in ...
- 洛谷 4290 [HAOI2008]玩具取名 题解
P4290 [HAOI2008]玩具取名 题目描述 某人有一套玩具,并想法给玩具命名.首先他选择WING四个字母中的任意一个字母作为玩具的基本名字.然后他会根据自己的喜好,将名字中任意一个字母用&qu ...
- github提示Permission denied (publickey),如何才能解决?
参考: https://my.oschina.net/u/1377923/blog/1822038 https://www.cnblogs.com/chjbbs/p/6637519.html
- [昆仑会员卡系统]老会员数据导入 从临时表插入会员至member_info_svc表 SQL
第一版无UUID版本 从临时表插入会员至member_info_svc表 insert into member_info_svc ( gh_no,chname,sex,birthday,tel,ema ...
- 未公开函数 NtQuerySystemInfoMation 遍历进程信息,获得进程的用户名(如: system,Admin..)
目录 遍历进程用户名 代码例子 遍历进程用户名 代码例子 #include <windows.h> #include <iostream> #include <COMDE ...
- Sublime Text 3 import Anaconda 无法正常补全模块名解决办法
Sublime Text 3 Anaconda配置 在安装Sublime Text3之后我们总会安装一些插件,比如Python的Anaconda自动补全插件.但是,装好之后发现import 时无法像别 ...
- 下载 Java
官网:https://www.java.com 官网可以下载到最新版本,如果需要下载旧版本的,可以访问: http://www.oracle.com/technetwork/java/archive- ...
- DevOps-如何构建持续交付流水线
引言 DevOps 是一套实践方法,在保证高质量的前提下缩短系统变更从提交到部署至生产环境的时间,其中持续集成和持续交付是 DevOps 里面非常重要的一环.本文讲述了达到自动化持续交付需要做的准备工 ...
- OpenFOAM显示残差
本文主要讲解两种方法用来显示OpenFOAM的计算残差,一种是采用OpenFOAM自带的foamMonitor来输出残差,另一种就是大家经常看见的采用pyFoam来输出残差.不管采用哪一种方法都必须安 ...