簡介
一個好的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效果。