android沈浸式狀態列實現
傳統的手機狀態列是呈現出黑色條狀的,有的和手機主介面有很明顯的區別。這樣就在一定程度上犧牲了視覺寬度,介面面積變小。
沉浸模式的狀態列和主介面完全融為了一體,在設計上有不同的視覺感受。
我們先上兩張圖,很容易看出區別:
Android在4.4的時候增加了透明狀態列與導覽列的功能,依託於這個新特性,我們可以開始跟隨潮流,實現Android的沈浸式狀態列 其實展示的這個關於介面的代碼非常簡單
/** * 關於介面 * * @author SuS * @time 2015.07.29 */public class AboutActivity extends BaseActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.setContentView(R.layout.activity_about); setImmerseLayout(findViewById(R.id.common_back)); initBackButton(); setTitleBar(R.string.durian_about); } @Override protected void onResume() { super.onResume(); } @Override protected void onPause() { super.onPause(); } @Override protected void onDestroy() { super.onDestroy(); }}現在請注意setImmerseLayout()這個方法,這個方法是在BaseActivity中實現的
public class BaseActivity extends FragmentActivity { private static final String TAG = BaseActivity; ............... public void initBackButton() { ImageView backButton = (ImageView) this.findViewById(R.id.durian_back_image); backButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finishActivity(); } }); } protected void setImmerseLayout(View view) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { Window window = getWindow(); /*window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);*/ window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); int statusBarHeight = ScreenUtil.getStatusBarHeight(this.getBaseContext()); view.setPadding(0, statusBarHeight, 0, 0); } } public void finishActivity() { finish(); overridePendingTransition(R.anim.push_right_in, R.anim.push_right_out); } public void setTitleBar(int id) { TextView tvName = (TextView) findViewById(R.id.durian_title_text); tvName.setText(id); }}使用 window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); 或者 window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
都可以使狀態列透明,但是關鍵是下面這兩行代碼,如果沒有這兩行,會是這樣
那麼這兩行神奇的代碼的原理是什嗎? 我們先看一下ScreenUtil中的getStatusBarHeight方法
/** * 用於擷取狀態列的高度。 使用Resource對象擷取(推薦這種方式) * * @return 返回狀態列高度的像素值。 */ public static int getStatusBarHeight(Context context) { int result = 0; int resourceId = context.getResources().getIdentifier(status_bar_height, dimen, android); if (resourceId > 0) { result = context.getResources().getDimensionPixelSize(resourceId); } return result; }
這裡是獲得狀態列的高度,然後我們就可以通過設定common_back的padding屬性 即:view.setPadding(0, statusBarHeight, 0, 0)來達到終極效果 但是這裡還是需要注意細節的,首先大家應該理解padding的含義:內邊距 那麼再看一下common_back的布局檔案 在activity_about.xml中我們是使用include引用的common_back
common_back的布局如下:
<framelayout android:background="@color/common_top_bg" android:id="@+id/durian_head_layout" android:layout_height="wrap_content" android:layout_width="match_parent" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> </framelayout>
這裡我們使用了一層FrameLayout包裹住RelativeLayout,這裡有什麼玄機那,其實這裡就是為了 方便上面那兩行神奇的代碼起作用,這樣我們就能設定RelativeLayout相對於FrameLayout的內邊距為狀態列的高度了 也就完美的達到了沈浸式狀態列的目的,而且保證導覽列的相對位置不變。
這裡存在一個common_back作為一個基準來控制高度達到狀態列的高度,如果一個activity只有一個背景圖片或者不以類似導覽列的空間作為基準的話,怎麼實現沈浸式狀態列,例如達到這種狀態 我們只需要在代碼這樣設定
protected void setImmerseLayout(View view) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { Window window = getWindow(); /*window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);*/ window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); /* int statusBarHeight = ScreenUtil.getStatusBarHeight(this.getBaseContext()); view.setPadding(0, statusBarHeight, 0, 0);*/ } }
然後在當前activity的布局檔案中加入這兩句話 android:fitsSystemWindows=true android:clipToPadding=true
這時候狀態列的背景與Activity的整個大背景融合在一起了
總結:
基於以上的方法介紹,我們可以實現狀態列與導覽列以及狀態列與頁面大背景的沈浸式體驗。
其實上面也可以看出代碼封裝的一些技巧:如讓我們所有的activity繼承BaseActivity,這樣像
setImmerseLayout(findViewById(R.id.common_back)); initBackButton(); setTitleBar(R.string.durian_about); 諸如此類的操作實現起來省時省力了!