简介
一个好的APP设计能够增强用户体验,留住用户,在UI上更加美观,给用户更加舒服的体验。而沉浸式设计能够使APP整体UI设计呈现一体化,使APP界面图片延伸到状态栏, 应用本身沉浸于状态栏。
沉浸式设计就是让人专注于当前的目标(有设计者营造)情境下感到愉悦和满足,而忘记真实世界的情景的设计方法。
Android沉浸式设计
对于Android5.0以后的API,已经自动实现了沉浸式效果了,状态栏会跟随你的主题colorPrimaryDark属性。5.0以后的API有三种方式可以设置沉浸式设计:
1)所以通过设置主题的样式即可达到沉浸式设计。
上图中在styles.xml指定主题样式即可。
2)在样式中设置android:statusBarColor
设置android:statusBarColor需要在API21(也就是5.0)以上才能支持。
3)通过代码设置
注意:这种方法设置需要放在setContentView方法之前设置,而且同样是需要在5.0以后的API才能设置。
Android5.0以后的版本使用沉浸式设计固然简单,但是唯一的缺点就是不支持低于5.0的版本,我们知道Android的绝大部分手机用户的版本还是在5.0以下的,这就需要我们做兼容开发了。
做沉浸式设计,目前最低只能兼容到4.4版本,低于Android4.4版本,是不可能做到沉浸式设计的,因为Android4.4新出的API,可以设置状态栏为透明状态,低于该版本就不能设置状态栏为透明状态,因此低于Android4.4版本不能做到沉浸式设计。
沉浸式兼容到Android4.4版本(一)
能够做到兼容到Android4.4版本的,需要我们做一些特殊处理,就是利用Android4.4版本新出的API,设置状态栏为透明状态。
两种方式可以设置状态栏为透明状态:
1)在属性样式里面设置
true 一般我们不会推荐使用这种方式,因为兼容性不好。
2)在代码里设置
注意:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);需要在setContentView方法之前设置。
下面给出该实例代码:
Activity:
public class TranslucentActivity01 extends AppCompatActivity {
private Toolbar mToolbar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//设置全屏
//getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
//设置透明状态栏
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
setContentView(R.layout.activity_translucent01);
mToolbar = (Toolbar)this.findViewById(R.id.tool_bar);
setSupportActionBar(mToolbar);
}
}
复制代码
xml布局:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.main.translucent.TranslucentActivity01">
<com.main.toolbar.MyScrollView
android:id="@+id/scrollView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ffffffff"
android:clipChildren="false"
android:clipToPadding="false"
android:paddingTop="?attr/actionBarSize">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<Button
android:id="@+id/button1"
style="?android:attr/buttonStyleSmall"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:text="Button0"/>
<Button
style="?android:attr/buttonStyleSmall"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:text="Button1"/>
<Button
style="?android:attr/buttonStyleSmall"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:text="Button2"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"/>
</LinearLayout>
</com.main.toolbar.MyScrollView>
<android.support.v7.widget.Toolbar
android:id="@+id/tool_bar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:fitsSystemWindows="true">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="标题"/>
</android.support.v7.widget.Toolbar>
</RelativeLayout>
复制代码
注意:
Toolbar需要添加android:fitsSystemWindows="true",否则APP的内容顶到最上面去了,即状态栏会遮挡一部分界面,该属性的作用:设置布局时,是否考虑当前系统窗口的布局,如果为true就会调整整个系统窗口,布局(包括状态栏的view)以适应你的布局。
运行效果
沉浸式兼容到Android4.4版本(二)
上面的沉浸式设计的方法已经可以兼容到Android4.4版本,但是还是有bug,当里面有ScrollView并且ScrollView里面有Edittext的时候,就会出现软键盘一弹起就会把toolbar拉下来。
在这里讲解第二种兼容方法,并且解决该bug:
1)同样需要在代码种设置状态栏的透明状态。
public class TranslucentActivity02 extends AppCompatActivity {
private Toolbar mToolbar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//设置透明状态栏
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
setContentView(R.layout.activity_translucent);
mToolbar = (Toolbar)this.findViewById(R.id.tool_bar);
setSupportActionBar(mToolbar);
}
}
复制代码
2)给布局最外层容器设置android:fitsSystemWindows="true"属性,并且给最外层容器(也可以修改android:windowBackground颜色)设置状态栏想要的颜色。
3)内容布局需要包裹一层并且设置背景颜色即可。
下面给出整个xml布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:background="?attr/colorPrimary"
tools:context="com.main.translucent.TranslucentActivity02">
<com.main.toolbar.MyScrollView
android:background="#ffffffff"
android:id="@+id/scrollView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clipChildren="false"
android:clipToPadding="false"
android:paddingTop="?attr/actionBarSize">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<Button
android:id="@+id/button1"
style="?android:attr/buttonStyleSmall"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:text="Button0"/>
<Button
style="?android:attr/buttonStyleSmall"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:text="Button1"/>
<Button
style="?android:attr/buttonStyleSmall"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:text="Button2"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"/>
</LinearLayout>
</com.main.toolbar.MyScrollView>
<android.support.v7.widget.Toolbar
android:id="@+id/tool_bar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:title="沉浸式03">
</android.support.v7.widget.Toolbar>
</RelativeLayout>
复制代码
得到的沉浸式效果图:
沉浸式兼容到Android4.4版本(三)
以上的方法都能够兼容到Android4.4版本,实现沉浸式设计,当然还有另外的方案可以实现沉浸式,那就是通过修改Toolbar的高度。
1)修改状态栏为透明状态;
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); setContentView(R.layout.activity_translucent03);
2)不需要给Toolbar设置android:fitsSystemWindows="true";
<android.support.v7.widget.Toolbar
android:id="@+id/tool_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary">
<TextView
android:layout_width="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_height="wrap_content"
android:text="标题"/>
</android.support.v7.widget.Toolbar>
复制代码
3)通过反射获取得到状态栏高度。
通过源码我们知道状态栏运行的类:android.R.dimen,其属性为status_bar_height
因此我们通过反射可以获取得到状态栏高度。
private int getStatusBarHeight(Context context){
// 反射运行的类:android.R.dimen.status_bar_height.
int mStatusHeight = -1;
try {
Class<?> mClass =Class.forName("com.android.internal.R$dimen");
Object object = mClass.newInstance();
String heightStr = mClass.getField("status_bar_height").get(object).toString();
int height = Integer.valueOf(heightStr);
//dp--->px
mStatusHeight = context.getResources().getDimensionPixelSize(height);
} catch (Exception e) {
e.printStackTrace();
}
return mStatusHeight;
}
复制代码
4)修改Toolbar的PaddingTop
下面是该实例的代码:
Activity:
public class TranslucentActivity03 extends AppCompatActivity {
private Toolbar mToolbar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
setContentView(R.layout.activity_translucent03);
mToolbar = (Toolbar) this.findViewById(R.id.tool_bar);
mToolbar.setPadding(
mToolbar.getPaddingLeft(),
mToolbar.getPaddingTop() + getStatusBarHeight(this),
mToolbar.getPaddingRight(),
mToolbar.getPaddingBottom());
}
/**
* 获取状态栏高度
*
* @param context
* @return
*/
private int getStatusBarHeight(Context context) {
// 反射运行的类:android.R.dimen.status_bar_height.
int mStatusHeight = -1;
try {
Class<?> mClass = Class.forName("com.android.internal.R$dimen");
Object object = mClass.newInstance();
String heightStr = mClass.getField("status_bar_height").get(object).toString();
int height = Integer.valueOf(heightStr);
//dp--->px
mStatusHeight = context.getResources().getDimensionPixelSize(height);
} catch (Exception e) {
e.printStackTrace();
}
return mStatusHeight;
}
}
复制代码
xml布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.main.translucent.TranslucentActivity03">
<com.main.toolbar.MyScrollView
android:background="#ffffffff"
android:id="@+id/scrollView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clipChildren="false"
android:clipToPadding="false"
android:paddingTop="?attr/actionBarSize">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<Button
android:id="@+id/button1"
style="?android:attr/buttonStyleSmall"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:text="Button0"/>
<Button
style="?android:attr/buttonStyleSmall"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:text="Button1"/>
<Button
style="?android:attr/buttonStyleSmall"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:text="Button2"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"/>
</LinearLayout>
</com.main.toolbar.MyScrollView>
<android.support.v7.widget.Toolbar
android:id="@+id/tool_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary">
<TextView
android:layout_width="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_height="wrap_content"
android:text="标题"/>
</android.support.v7.widget.Toolbar>
</RelativeLayout>
复制代码
运行效果图:
沉浸式兼容到Android4.4版本(四)
除了以上的实现方式,当然我们可以使用第三方来实现Android的沉浸式设计。这里实例采用的是SystemTint第三方。
1)在app下的build.gradle添加依赖
2)新建BaseActivity,统一处理,新的Activity只需要继承BaseActivity即可。
public class BaseActivity extends AppCompatActivity {
private SystemBarTintManager tintManager;
private boolean mIsOpenBar = true;
private int color = 0xff3F51B5;//默认颜色
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initTint();
}
/**
* 是否需要实现沉浸式
* @param openBar
*/
public void setOpenBar(boolean openBar) {
mIsOpenBar = openBar;
}
/**
* 设置沉浸式颜色
* @param color
*/
public void setColor(int color) {
this.color = color;
if (mIsOpenBar){
setTintBar(color);
}
}
/**
* 初始化
*/
private void initTint() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
// create our manager instance after the content view is set
tintManager = new SystemBarTintManager(this);
// enable status bar tint
tintManager.setStatusBarTintEnabled(true);
// enable navigation bar tint
tintManager.setNavigationBarTintEnabled(true);
if (mIsOpenBar){
setTintBar(color);
}
}
/**
* 设置沉浸式
* @param color
*/
private void setTintBar(int color) {
// set a custom tint color for all system bars
tintManager.setTintColor(color);
// set a custom navigation bar resource
tintManager.setNavigationBarTintColor(color);
// set a custom status bar drawable
tintManager.setStatusBarTintColor(color);
// tintManager.setStatusBarTintResource(R.color.colorAccent);
}
}
复制代码
初始化SystemTint和设置状态栏颜色等等在BaseActivity处理即可。具体可查看注释。
3)新Activity继承BaseAcitivity,通过setColor来设置状态栏颜色即可。
public class TranslucentActivity04 extends BaseActivity {
private Toolbar mToolbar;
//需要在根布局加入一下的
// android:clipToPadding="false"
// android:fitsSystemWindows="true"
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_translucent04);
mToolbar = (Toolbar) this.findViewById(R.id.tool_bar);
this.findViewById(R.id.button1).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
setColor(0xffffD306);
mToolbar.setBackgroundColor(0xffffD306);
}
});
}
}
复制代码
4)xml布局的根布局需要添加
android:clipToPadding="false"和android:fitsSystemWindows="true"属性
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:fitsSystemWindows="true"
tools:context="com.main.translucent.TranslucentActivity04">
<com.main.toolbar.MyScrollView
android:id="@+id/scrollView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ffffffff"
android:paddingTop="?attr/actionBarSize">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<Button
android:id="@+id/button1"
style="?android:attr/buttonStyleSmall"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:text="Button0"/>
<Button
style="?android:attr/buttonStyleSmall"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:text="Button1"/>
<Button
style="?android:attr/buttonStyleSmall"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:text="Button2"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"/>
</LinearLayout>
</com.main.toolbar.MyScrollView>
<android.support.v7.widget.Toolbar
android:id="@+id/tool_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="标题"/>
</android.support.v7.widget.Toolbar>
</RelativeLayout>
复制代码
运行效果图:
通过以上的学习,我们可以做出Android的沉浸式设计效果,并且能够兼容到Android4.4版本,给用户精美的UI效果。