標籤:
在上一篇文章中介紹了一種設定透明狀態列及其適配鍵盤上推得方法。但是上一篇介紹的方法中有個缺點,就是不能消除掉statusbar的陰影。很多手機如(三星,Nexus都帶有陰影)。即使我用了:
<android.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" app:elevation="0dp" android:background="@android:color/transparent" android:theme="@style/AppTheme.AppBarOverlay"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="@android:color/transparent" app:popupTheme="@style/AppTheme.PopupOverlay" /> </android.support.design.widget.AppBarLayout>
還是不能消除陰影。那怎麼辦呢?這裡介紹一種我覺得還不錯的方法,思路是:不用toolbar,直接通過代碼設定介面為透明statusbar,在每個介面裡增加一個statusbar高度的view用來適配介面的顯示,否則介面最頂端會有部分被statusbar覆蓋。
方法如下:
1. 修改您應用裡每個介面裡的最頂端的布局:
<RelativeLayout android:id="@+id/total_tile_id" android:layout_width="match_parent" android:layout_height="wrap_content"> <RelativeLayout android:id="@+id/actionbar_tile_bg" android:layout_width="match_parent" android:layout_height="wrap_content"> </RelativeLayout> <!--titlebar的其他布局--></RelativeLayout>
2. 在activity的onCreate方法中(最好寫在baseActivity裡),增加如下代碼,設定為透明statusbar同時清除背景陰影。
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);//透明狀態列 // 狀態列字型設定為深色,SYSTEM_UI_FLAG_LIGHT_STATUS_BAR 為SDK23增加 getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);// // 部分機型的statusbar會有半透明的黑色背景 getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); getWindow().setStatusBarColor(Color.TRANSPARENT);// SDK21
3.同時在activity的onCreate方法中(最好寫在baseActivity裡),調用initMarginTopWithStatusBarHeight方法
/** * 設定view的margintop高度為statusbar高度 * @param view 就是上面的 actionbar_tile_bg 這個view * @param context */public static void initMarginTopWithStatusBarHeight(View view,Context context){ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null){ view.setVisibility(View.VISIBLE); RelativeLayout.LayoutParams rl = new RelativeLayout.LayoutParams(view.getLayoutParams()); rl.topMargin = getStatusBarHeight(context); view.setLayoutParams(rl); }else{ view.setVisibility(View.GONE); } }
這樣就可以實現6.0以上的機型statusbar為透明且沒有陰影(6.0以下的沒有測試過,我這個應用的需求就是要求6.0以上,有興趣的同學可以去測試下)。
但是這樣設定後,用上一篇的適配鍵盤上推或是虛擬按鍵的顯示和隱藏適配就不行了,需要重新設定。
增加一個util類:
public class AndroidBug5497Workaround { // For more information, see https://code.google.com/p/android/issues/detail?id=5497// To use this class, simply invoke assistActivity() on an Activity that already has its content view set. public static void assistActivity (final Activity activity) { new AndroidBug5497Workaround(activity); } private View mChildOfContent; private int usableHeightPrevious; private FrameLayout.LayoutParams frameLayoutParams; private AndroidBug5497Workaround(final Activity activity) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content); mChildOfContent = content.getChildAt(0); mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { public void onGlobalLayout() { possiblyResizeChildOfContent(activity); } }); frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams(); } } private void possiblyResizeChildOfContent(Activity activity) { int usableHeightNow = computeUsableHeight(); if (usableHeightNow != usableHeightPrevious) { int resourceId = activity.getResources().getIdentifier("navigation_bar_height", "dimen", "android"); //擷取NavigationBar的高度 int navigateHeight = activity.getResources().getDimensionPixelSize(resourceId); boolean hasSoftNavigateBar = navigationBarExist2(activity); int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight(); int heightDifference = usableHeightSansKeyboard - usableHeightNow; if (heightDifference > (usableHeightSansKeyboard/4) || hasSoftNavigateBar) { if (heightDifference == 0){ heightDifference = navigateHeight; } // keyboard probably just became visible frameLayoutParams.height = usableHeightSansKeyboard - heightDifference; } else { // keyboard probably just became hidden frameLayoutParams.height = usableHeightSansKeyboard; } mChildOfContent.requestLayout(); usableHeightPrevious = usableHeightNow; } } private int computeUsableHeight() { Rect r = new Rect(); mChildOfContent.getWindowVisibleDisplayFrame(r); return r.bottom; } /** * 判斷是否虛擬按鍵,這個方法最管用 * @param activity * @return */ private boolean navigationBarExist2(Activity activity) { WindowManager windowManager = activity.getWindowManager(); Display d = windowManager.getDefaultDisplay(); DisplayMetrics realDisplayMetrics = new DisplayMetrics(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { d.getRealMetrics(realDisplayMetrics); } int realHeight = realDisplayMetrics.heightPixels; int realWidth = realDisplayMetrics.widthPixels; DisplayMetrics displayMetrics = new DisplayMetrics(); d.getMetrics(displayMetrics); int displayHeight = displayMetrics.heightPixels; int displayWidth = displayMetrics.widthPixels; return (realWidth - displayWidth) > 0 || (realHeight - displayHeight) > 0; }}
在activity裡onCreate裡調用:
AndroidBug5497Workaround.assistActivity(this);
OK,這兩篇是我在開發過程中遇到的問題,記錄並分享。
android 透明狀態列方法及其適配鍵盤上推(二)