上一篇文章《Android沉浸式設計》中我們學習了Android的沉浸式設計,那麼我們可不可以對上篇文章學習的內容做一個封裝呢,另外除了狀態列實現了沉浸式,有些手機是有虛擬導航欄的,比如華為系列的手機,那麼我們可以不可以也實現對底部導航欄的沉浸式設計呢?當然是可以的,本文就帶你實現沉浸式封裝(包括狀態列和底部導航欄)。
封裝最好是在BaseActivity裡面,這樣子每一個繼承BaseActivity的Activity都可以自動實現沉浸式。
這裡使用上一篇文章《Android沉浸式設計》用到的技術進行封裝: 狀態列:設定狀態列為透明狀態,通過反射獲取狀態列的高度,然後給toolbar設定PaddingTop。 導航欄:設定導航欄為透明狀態,需要預設一個高度為1或者0的view,然後獲取導航欄高度,把導航欄的高度設定為View的高度,給View設定背景即可。
1)BaseActivity
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);
}
}
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的高度
ViewGroup.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())) {
ViewGroup.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的,不做處理
}
}
/**
* 獲取導航欄高度
* @param context
* @return
*/
private int getNavigationBarHeight(Context context) {
return getSystemComponentDimen(this, "navigation_bar_height");
}
/**
* 獲取狀態列的高度
*
* @param context
* @return
*/
private int getStatusBarHeight(Context context) {
// 反射手機執行的類:android.R.dimen.status_bar_height.
return getSystemComponentDimen(this, "status_bar_height");
}
/**
* 反射獲取高度
* @param context
* @param dimenName
* @return
*/
private static int getSystemComponentDimen(Context context, String dimenName) {
// 反射手機執行的類:android.R.dimen.status_bar_height.
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;
}
/**
* 判斷是否顯示導航欄
* @param wm
* @return
*/
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
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;//豎屏和橫屏兩種情況。
}
}
複製程式碼
BaseTranslucentActivity的所做的事情基本在上面已經分析了,如果還有不明白的可以檢視註釋。
2)activity需要繼承BaseActivity
public class TranslucentActivity06 extends BaseTranslucentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_translucent06);
final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
setOrChangeTranslucentColor(toolbar,null,0xffffD306);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
setOrChangeTranslucentColor(toolbar,null,0xffffD3ff);
}
});
}
}
複製程式碼
這裡需要手動呼叫setOrChangeTranslucentColor
方法設定沉浸式。
3)xml佈局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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:background="?attr/colorPrimary"
android:orientation="vertical"
tools:context="com.main.translucent.TranslucentActivity07">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/ThemeOverlay.AppCompat.Dark"
app:title="@string/app_name"
app:titleTextColor="#ff0"
>
</android.support.v7.widget.Toolbar>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#fff">
<android.support.v7.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:divider="@drawable/abc_list_divider_mtrl_alpha"
app:showDividers="beginning|middle">
<android.support.v7.widget.AppCompatButton
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="24dp"
android:layout_marginTop="23dp"
android:onClick="showDialog"
android:text="對話方塊"/>
<CheckBox
android:id="@+id/checkBox1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="CheckBox"/>
<RadioButton
android:id="@+id/radioButton1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="RadioButton"/>
</android.support.v7.widget.LinearLayoutCompat>
</ScrollView>
<View
android:id="@+id/nav"
android:layout_width="fill_parent"
android:layout_height="1dp"
android:layout_weight="0"
android:background="?attr/colorPrimary"
/>
</LinearLayout>
複製程式碼
注意:這裡底部預設了一個View給導航欄。如果不想改變導航欄的,可以不預設,呼叫setOrChangeTranslucentColor方法的時候,第二個引數直接傳null即可。
執行效果圖:
以上程式碼的BaseTranslucentActivity類就是實現沉浸式設計的封裝,哪裡不明白的或者你有更好的設計方案,歡迎致信,一起交流。